【发布时间】:2011-09-03 12:47:16
【问题描述】:
采用private string Property {get; set;} 与private string field。
请注意,两者都是私有的(因此它们不会暴露在此类之外)并且该属性没有采用额外的验证。
关于语义,它们有不同的含义吗?从某种意义上说,它们在这样使用时可以互换吗?
当涉及到诸如(微?)性能之类的影响时,创建字段还是创建属性是否重要,即让编译器为您处理支持字段。
【问题讨论】:
采用private string Property {get; set;} 与private string field。
请注意,两者都是私有的(因此它们不会暴露在此类之外)并且该属性没有采用额外的验证。
关于语义,它们有不同的含义吗?从某种意义上说,它们在这样使用时可以互换吗?
当涉及到诸如(微?)性能之类的影响时,创建字段还是创建属性是否重要,即让编译器为您处理支持字段。
【问题讨论】:
当它们是私有的时,我知道的唯一区别是该属性不适合 out 和 ref 参数。
但大多数情况下,私有财产并没有带来任何优势(相对于一个领域),那何必呢?
可能存在(微)性能成本。我会更担心额外的混乱。
【讨论】:
性能影响:
使用属性(自动或带有支持字段)与字段相比有轻微的性能,因为属性是一种方法并且需要调用 CLR virtcall。
但正如我所说,使用属性并没有多大意义,我相信 字段更具可读性,因为通常可以立即通过 命名约定(以 下划线或驼峰式)。
【讨论】:
您不能拥有对属性的引用,但可以获取对成员的引用。因此,如果您使用成员,您可能无法在以后出于任何原因将它们切换到属性,例如添加臭名昭著的验证。
【讨论】:
ref 传递给成员(例如,可以将其提供给Interlocked 方法),则使用属性可能会强制使用更笨重的设计.如果由于某种原因最终无法避免使用属性,那么最好从使用笨重的设计开始,而不是使用干净的设计来实施系统,然后在现场使用笨拙的设计时将其替换为笨拙的设计。替换为属性。另一方面,如果成员永远不需要成为属性,则最好使用更简洁的设计。
我认为创建私有自动属性没有用。如果它不是自动的,它可以用作某种内部“事件处理程序”以使对象状态保持最新:每次字段更改时(通过设置器)在代码中的任何位置执行一些操作。
性能?我认为不会有问题,即使在微观层面上也不会。
【讨论】:
属性是函数。
字段是“至少具有类可见性的变量”。
所以如果你有私有财产和私有领域:
如果您使用优化并且没有跟踪(属性被视为内联),则没有区别。
1) 形式上没有区别。
2) 更深入一点,有区别。由于属性是函数,因此您可以从 getter 和 setter 获得委托。并且可以将委托用作...委托,就像将此委托与其他委托一起放入列表中一样 (Create a delegate from a property getter or setter method)
但是属性是看起来像变量的函数。为什么需要看起来像变量的函数?
假设你有 Hand 类,而这只手有可变的指数。
class Hand
{
public int fingersNumber;
}
那你可能有很多类似的代码
if(he is BadPerson) leftHand.fingersNumber--
if(doctor.Heal()) leftHand.fingersNumber++
但在某些时候,您可能希望向 Hand 添加一些其他变量。可以说它是环数。而且您知道,每个手指的戒指不能超过 10 个。
class Hand
{
public int fingersNumber;
public int ringsNumber;
}
现在,你不能只是这样做
leftHand.fingersNumber--
因为你必须控制ringsNumber 对fingersNumber 的依赖。
因此,您必须创建一些检查这种依赖性的函数。此外,您必须对用户隐藏 FingerNumber 和 RingNumber,这样他们就无法在没有检查的情况下更改此字段。
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反汇编或只是谷歌关于它。
【讨论】: