属性和字段之间的语义差异及其含义

本文关键字:语义 字段 之间 属性 | 更新日期: 2023-09-27 17:57:46

private string Property {get; set;}private string field

请注意,两者都是私有的(因此它们不会在此类之外公开),并且属性没有使用额外的验证

关于语义,它们有不同的含义吗?从这个意义上说,当这样使用时,它们可以互换吗?

当涉及到含义时,例如(micro?)性能,是否创建字段与属性(即让编译器为您处理后台字段)有关系。

属性和字段之间的语义差异及其含义

当它们是私有的时,我所知道的唯一区别是该属性不适合outref参数。

但大多数情况下,私人财产(相对于油田)不会带来任何优势,所以为什么要麻烦呢
可能存在(微观)性能成本。我会更担心额外的杂物。

  • 属性是关于字段的数据隐藏
  • 私人财产并不意味着什么,因为无论谁有权进入该财产,都将有权进入油田
  • 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反汇编或只是在谷歌上搜索它。