属性和字段之间的语义差异及其含义
本文关键字:语义 字段 之间 属性 | 更新日期: 2023-09-27 17:57:46
取private string Property {get; set;}
与private string field
。
请注意,两者都是私有的(因此它们不会在此类之外公开),并且属性没有使用额外的验证
关于语义,它们有不同的含义吗?从这个意义上说,当这样使用时,它们可以互换吗?
当涉及到含义时,例如(micro?)性能,是否创建字段与属性(即让编译器为您处理后台字段)有关系。
当它们是私有的时,我所知道的唯一区别是该属性不适合out
和ref
参数。
但大多数情况下,私人财产(相对于油田)不会带来任何优势,所以为什么要麻烦呢
可能存在(微观)性能成本。我会更担心额外的杂物。
- 属性是关于字段的数据隐藏
- 私人财产并不意味着什么,因为无论谁有权进入该财产,都将有权进入油田
- auto属性与backing字段之间没有性能关系,因为编译器吐出backing字段,但可能存在串行化/去串行化警告
更新
性能影响:
由于属性是一种方法,需要调用CLR virtcall
,因此使用属性(auto或带backing字段)vs字段会有轻微的性能。
但正如我所说,使用属性没有多大意义,我相信字段更具可读性,因为命名约定通常可以立即看到(以下划线或驼色大小写开头)。
您不能引用属性,但可以获得对成员的引用。因此,如果您使用成员,以后可能会因为任何原因(例如添加臭名昭著的验证)而难以将它们切换到属性。
创建一个私有的自动属性没有任何用处。如果它不是自动的,它可以用作某种内部"事件处理程序"来保持对象状态的最新状态:每次字段在代码中的任何位置更改(通过setter)时都执行一些操作。
性能?我不认为会有什么问题,甚至在微观层面上也不会。
属性是函数
字段是"至少具有类可见性的变量"。
所以,如果你有私人财产与私人领域:
与性能点的差异:
如果使用优化和无跟踪(属性被视为内联),则没有区别。
语义上的差异:
1) 形式上没有区别
2) 更深入地说,存在差异。由于属性是函数,您可以从getter和setter获得委托。并且可以将委托用作…委托,就像将此委托与其他委托一起放入列表一样(从属性getter或setter方法创建委托)
与设计视图的区别:
但属性是看起来像变量的函数。为什么需要看起来像变量的函数?
假设你有类Hand,而这只手有可变的fingersNumber。
class Hand
{
public int fingersNumber;
}
然后你可能会有很多像这样的代码
if(he is BadPerson) leftHand.fingersNumber--
if(doctor.Heal()) leftHand.fingersNumber++
但在某些情况下,您可能需要向Hand添加一些其他变量。假设它是ringsNumber。你知道,每个手指的戒指不能超过10个
class Hand
{
public int fingersNumber;
public int ringsNumber;
}
现在,你不能只做
leftHand.fingersNumber--
因为你必须控制ringsNumber对fingersNumber的依赖性。
所以你必须创建一些函数来检查这种依赖性。此外,你必须向用户隐藏手指号码和环号码,这样他们就不能在没有检查的情况下更改此字段。
class Hand
{
private int fingersNumber;
private int ringsNumber;
public int GetFingersNumber(){...check logic...}
public void SetFingersNumber(int value){...check logic...}
public int GetRingsNumber(){...check logic...}
public void SetRingsNumber(int value){...check logic...}
}
并将此功能用作
if(he is BadPerson) leftHand.SetFingersNumber(leftHand.GetFingersNumber()-1)
这里的问题是旧代码leftHand.fingersNumber--现在无法工作。从一开始,你就不知道未来会有戒指。为了解决这些问题,将字段设置为私有字段,并使用set和Get函数来获取和更改变量,这成为了一种范式,并确保将来可以在那里添加任何逻辑,代码就会工作!
Setters和Getters是C++、Java和许多语言中的一种现状但C#创建者更进一步,将getter和setter函数修饰为"属性"。
class Hand
{
private int fingersNumber;
public int FingersNumber
{
get{return fingersNumber;}
set{fingersNumber=value;}
}
...
}
...
if(he is BadPerson) leftHand.FingersNumber--;
但大多数时候,人们创建这样简单的属性,您可以看到这个例子,它是5行例程代码。因此,在C#的某个版本中,添加了自动属性来简化程序员的生活。所以你的课可能看起来像
class Hand
{
public int FingersNumber{get;set;}
}
但在任何时候,你都可以扩展这种设置行为:
class Hand
{
private int fingersNumber;
public int FingersNumber
{
get{...check logic...}
set{...check logic...}
}
...
}
而且它不会制动任何代码。像
if(he is BadPerson) leftHand.FingersNumber--;
这就是属性,为什么使用它们,以及字段的区别。
正如我前面所说,如果使用优化,简单属性和自动属性与变量具有相同的性能。Se反汇编或只是在谷歌上搜索它。