为什么使用私有成员然后使用公共属性来设置它们?

看到发生这种情况的一些代码示例:

public class Foo { string[] m_workID; public string[] WorkID { get { return m_workID; } private set { m_workID = value; } } } 

这有什么意义? 由于使用m_workID不必要。

通常,重点是将实现 (字段)与API (属性)分开。

如果你愿意,你可以在不破坏源代码或二进制兼容性的情况下将逻辑,日志记录等放入属性中 – 但更重要的是,你要说的是你的类型愿意做什么,而不是它将如何做。

我有一篇文章给出了使用属性而不是公共字段的更多好处。

在C#3中,您可以使用自动实现的属性使所有这些变得更加简单:

 public class Foo { public string[] WorkID { get; private set; } } 

此时你仍然有一个公共getter和一个私有的setter,但是在幕后为你生成了支持字段(和属性实现)。 在任何时候,您都可以将其更改为具有支持字段的“正常”完全实现的属性,并且您仍将具有二进制和源兼容性。 (序列化对象的兼容性是另一回事,请注意。)

此外,在这种情况下,您无法使用字段镜像所需的行为(公开读取值但私下写入它) – 您可以拥有只读字段,但之后只能在构造函数中写入它。 我个人希望有一个类似的简写:

 public class Foo { private readonly int id; public int Id { get { return id; } } ... } 

因为我喜欢不可变类型,但这是另一回事。

另一个不同的问题上,无论如何暴露这样的数组通常不是一个好主意 – 即使调用者不能改变WorkID引用的数组,他们也可以改变数组的内容,这可能不是你想要的。

在您给出的示例中,您可以在没有属性设置器的情况下离开,只需将字段直接设置在同一个类中,但这意味着如果您想要添加日志记录等,则必须找到所有这些写入。

一个属性本身并不提供放置数据的任何地方 – 你需要字段( m_workID )来存储,但由于许多原因,它完全正确地隐藏在属性后面。 在C#3.0中,您可以将其减少为:

  public string[] WorkID {get; private set;} 

哪个会做很多相同的事情。 请注意,暴露数组本身可能会有问题,因为没有用于保护数组中数据的机制 – 至少使用IList您可以(如果需要)添加额外的代码以进行健全性检查,或者可以使其不可变。 我不是说这需要修复,但需要注意。

除了面向对象的数据封装理念外,每当您的属性读/写时需要执行某些操作时,它也会有所帮助。 您可以在以后的开发中执行日志,validation或任何其他方法调用。

如果您的财产是公开的,则必须查看所有代码以查找和修改您的代码。 如果您的代码被其他人用作库,该怎么办?

如果你的属性是私有的,有适当的get / set方法,那么你改变了get / set,那就是全部。

您可以使用C#3.0自动属性function来节省键入时间:

 public class Foo { public string[] WorkID { get; private set; } } 

此外,与字段相比,属性为您提供了许多优势:

  • 属性可以是虚拟的

  • 属性隐藏实现细节(并非所有属性都只是简单的变量访问器)

  • 属性可以包含validation和日志记录代码并引发更改事件

  • 接口不能包含字段但属性

很多时候,您只想提供对字段的读取权限。 通过使用属性,您可以提供此访问权限。 如您所述,您可能希望在访问字段之前执行操作(例如,延迟加载)。 你有很多代码,除非你还在.Net 2.0-工作,否则就不再需要了。