在C#中,是什么使字段与属性不同?何时应该使用字段而不是属性?
当前回答
基本区别和一般区别是:
领域
始终给予get和set访问权限不会造成副作用(引发异常、调用方法、更改字段(获取/设置的字段除外)等)
财产
并非总是同时提供get和set访问权限CAN导致副作用
其他回答
财产支持非对称访问,即您可以有getter和setter,也可以只有这两者之一。类似地,财产支持getter/setter的单独可访问性。字段始终是对称的,即您始终可以获取和设置值。例外情况是只读字段,在初始化后显然无法设置。
财产可能运行很长时间,有副作用,甚至可能引发异常。字段很快,没有副作用,并且不会抛出异常。由于副作用,属性可能会为每个调用返回不同的值(DateTime.Now可能就是这样,即DateTime.Nnow不总是等于DateTime.NNow)。字段总是返回相同的值。
字段可以用于out/ref参数,财产则不能。财产支持额外的逻辑–这可以用于实现延迟加载等。
财产通过封装获取/设置值的任何含义来支持抽象级别。
在大多数/所有情况下使用财产,但尽量避免副作用。
当你有一节课是“汽车”时。财产包括颜色、形状。。
其中as字段是在类范围内定义的变量。
由于他们中的许多人已经解释了财产和Field的技术优缺点,现在是时候进入实时示例了。
1.财产允许您设置只读访问级别
考虑dataTable.Rows.Count和dataTable.Column[i].Caption的情况。它们来自dataTable类,对我们来说都是公共的。对它们的访问级别的不同之处在于,我们不能将值设置为dataTable.Rrows.Count,但我们可以读写dataTable.Colomn[i].Taption。这可以通过Field实现吗?不这只能通过财产完成。
public class DataTable
{
public class Rows
{
private string _count;
// This Count will be accessable to us but have used only "get" ie, readonly
public int Count
{
get
{
return _count;
}
}
}
public class Columns
{
private string _caption;
// Used both "get" and "set" ie, readable and writable
public string Caption
{
get
{
return _caption;
}
set
{
_caption = value;
}
}
}
}
2.PropertyGrid中的财产
您可能在Visual Studio中使用了Button。它的财产显示在PropertyGrid中,如Text、Name等。当我们拖放按钮时,当我们单击财产时,它将自动找到类button并过滤财产,并在Property Grid中显示该类(其中PropertyGrid不会显示Field,即使它们是公共的)。
public class Button
{
private string _text;
private string _name;
private string _someProperty;
public string Text
{
get
{
return _text;
}
set
{
_text = value;
}
}
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
[Browsable(false)]
public string SomeProperty
{
get
{
return _someProperty;
}
set
{
_someProperty= value;
}
}
在PropertyGrid中,将显示财产Name和Text,但不显示SomeProperty。为什么?因为财产可以接受属性。如果[可浏览(false)]为false,则不会显示。
3.可以在财产中执行语句
public class Rows
{
private string _count;
public int Count
{
get
{
return CalculateNoOfRows();
}
}
public int CalculateNoOfRows()
{
// Calculation here and finally set the value to _count
return _count;
}
}
4.绑定源中只能使用财产
绑定源帮助我们减少代码行数。BindingSource不接受字段。为此,我们应该使用财产。
5.调试模式
考虑我们使用Field来保存值。在某些时候,我们需要调试并检查该字段的值在哪里变为空。当代码行数超过1000行时,这将很难做到。在这种情况下,我们可以使用Property,并可以在Property中设置调试模式。
public string Name
{
// Can set debug mode inside get or set
get
{
return _name;
}
set
{
_name = value;
}
}
从技术上讲,我不认为有什么区别,因为财产只是围绕用户创建的或编译器自动创建的字段的包装器。财产的目的是加强封装,并提供轻量级的类方法功能。将字段声明为公共字段是一种不好的做法,但它没有任何问题。
其他信息:默认情况下,get和set访问器与属性本身一样可访问。通过对访问器应用更严格的访问修饰符,可以分别控制/限制访问器的可访问性(对于get和set)。
例子:
public string Name
{
get
{
return name;
}
protected set
{
name = value;
}
}
这里get仍然是公共访问的(因为属性是公共的),但set是受保护的(一个更受限制的访问说明符)。