属性公开字段。字段应该(几乎总是)保持对类的私有,并通过 get 和 set 属性进行访问。属性提供了一个抽象级别,允许您更改字段,同时不影响使用您的类的东西访问它们的外部方式。
public class MyClass
{
// this is a field. It is private to your class and stores the actual data.
private string _myField;
// this is a property. When accessed it uses the underlying field,
// but only exposes the contract, which will not be affected by the underlying field
public string MyProperty
{
get
{
return _myField;
}
set
{
_myField = value;
}
}
// This is an AutoProperty (C# 3.0 and higher) - which is a shorthand syntax
// used to generate a private field for you
public int AnotherProperty{get;set;}
}
@Kent 指出,属性不需要封装字段,它们可以在其他字段上进行计算,或用于其他目的。
@GSS 指出,当访问属性时,您还可以执行其他逻辑,例如验证,这是另一个有用的功能。
面向对象的编程原则说,类的内部工作应该隐藏在外部世界之外。如果您公开一个字段,那么您实际上是暴露了该类的内部实现。因此,我们使用 Properties(或 Java 的方法)来包装字段,以使我们能够在不破坏代码的情况下更改实现,具体取决于我们。看到我们可以在属性中放置逻辑也允许我们在需要时执行验证逻辑等。 C#3 有可能令人困惑的 autoproperties 概念。这允许我们简单地定义属性,C#3 编译器将为我们生成私有字段。
public class Person
{
private string _name;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
public int Age{get;set;} //AutoProperty generates private field for us
}
一个重要的区别是接口可以具有属性但不具有字段。对我来说,这强调了属性应该用于定义类的公共接口,而字段用于在类的私有内部工作中使用。作为一项规则,我很少创建公共字段,同样我很少创建非公共属性。