为什么我需要使用get和set?

我有一个代码段:

public class MyClass { private string _myProperty; public string MyProperty { get { return _myProperty; } set { _myProperty = value; } } } 

这有什么意义? 我可以将_myProperty字符串声明为public,我的任何类对象都可以直接访问它们并获取或设置值。

相反,我们使用类对象将_myProperty私有,并使用get和set来访问它们。

在任何一种情况下,类对象都能够访问它们,结果总是相同的。

那么为什么要用这种方法? 这只是因为我可以在setter中实现一些约束吗?

除此之外会对成员变量造成什么危害呢? 在这个例子中,我可以将_myProperty公开为public,而不是像OOP所暗示的那样只将它限制为私有。

不,结果并不总是一样的。

  • 尝试绑定到公共字段(或执行任何其他使用reflection和期望属性的字段)
  • 尝试通过引用传递属性(你不能)
  • 稍后尝试确定您希望记录等,并发现当您将其更改为属性时,您将失去源和二进制兼容性。

阅读我刚才写的这篇文章 ……

请注意,从C#2开始,您的代码可以缩短很多

 public class MyClass { public string MyProperty { get; set; } } 

字段_myProperty是一个实现细节 – 它告诉编译器你想要一些字符串引用的存储并给它那个名字。 get / set方法是对象属性的一部分,它抽象了MyProperty属性的实现方式。 因此,如果您想要更改字符串的存储/检索方式,第三方依赖者不必重新编译。

您还可以使用自动属性为您执行此操作:

 public string MyProperty {get; set;} 

如果您只是将变量声明为Public,则这些实际上不是Properies。 许多使用reflection的function都不起作用,特别是DataBinding,Serialization等。

偶尔我会变得懒惰并且这样做,特别是在VB.Net pre v4中工作,因为没有自动属性,并且总是后悔并返回正确编写属性。

如果您的类要由非自己的开发人员编写的代码使用,那么使用属性尤为重要,因为他们可能会遇到因不编码完整属性而产生的限制问题。

正如您所说,属性的主要原因是validation。 每个class级都有责任保证他们的成员安全,_myProperty是MyClass的成员。 .Net实现这一责任的方式是有意义的。 在Java中,您必须定义两个方法:SetMyPropety和GetMyProperty。

重要的是要注意,尽管类通常有助于在属性中包装字段,但对于结构来说这通常会适得其反。 关于结构使用的许多建议限制源于假设所有结构域都将包含在属性中。 如果struct的语义提供:

  1. 它的状态完全由固定数量的参数定义,所有参数都公开暴露用于阅读。
  2. 可以自由地为这些参数分配对于它们各自类型合法的值的任何组合。
  3. 结构的默认实例被指定为将所有参数初始化为其各自类型的默认值。

然后暴露字段将暴露数据类型的“内部工作”,但这种曝光不会排除对数据类型的任何有意义的未来更改,这些更改尚未被规范排除 。 存储在可修改位置的所有结构的所有字段总是暴露出来进行变异,即使唯一的变异方法是从一个实例到另一个实例的所有公共和私有字段的批量副本。 如果结构的语义要求代码能够创建一个实例,其定义参数具有值的任意组合,而没有限制,直接暴露结构的字段将不允许单线程代码执行任何无法执行的操作慢慢没有这样的访问。 暴露字段的唯一事情将允许代码执行,否则它将无法做到:

  1. 执行得更快
  2. 更清楚地表达其意图
  3. 已经在multithreading场景中定义了语义,否则语义会变得模糊不清

要求类型的消费者运行速度较慢,写得笨拙,并且具有模糊的multithreading语义,我并没有看到太多好处。

请注意,如果有一个策略反对使用具有变异’this’的属性的结构,而不是封装所有结构字段的策略,那么语句如下:

 myListOfPoint[4].X = 5; 

即使语言允许在只读结构上调用属性设置器,也会被拒绝(假设目的是为了像

 myArraySegment[3] = 9; 

这将被理解为访问myArraySegment包含引用的数组。