string name;
Run Code Online (Sandbox Code Playgroud)
VS
string name {get; set;}
Run Code Online (Sandbox Code Playgroud)
假设你的get和set如上所述是空白的,那么指定它们有什么意义呢?
pic*_*ypg 24
它封装领域产生的编译器,并提供你的,class或struct开发人员无需通过简单修改破坏你的API在内部以后更新它的能力get/ set你关心的部分.
比如,突然之间永远不想回归null?您只需将空值更改为get即可get { return storedName ?? ""; }.当然,这意味着你突然需要手动控制变量,但这是一个支付灵活性的小代价.
第一个用途是字段声明的示例.第二个用途是自动实现的属性的示例.
提供直接访问字段通常是不好的做法.然而,.NET团队注意到很多getter/setter基本就是这样.例如,请考虑以下事项:
// C#
public string Name
{
get { return name; }
set { name = value; }
}
// Without properties (or a Java implementation)
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
Run Code Online (Sandbox Code Playgroud)
无论哪种方式,真正暴露一个领域真是太多了.但是,通常情况下,作为开发人员,您需要返回并更改内部处理字段的方式,但如果您可以侥幸逃脱,则不希望破坏甚至影响其他代码.
这就是为什么使用直接访问字段是不好的.如果您提供对字段的直接访问,但需要更改使用该字段的内容,则使用该字段的所有代码也必须更改.如果使用属性(甚至方法),则可以更改内部代码,并且可能不会影响外部代码.
请考虑以下示例:
public string Name
{
get;
set;
}
Run Code Online (Sandbox Code Playgroud)
之后您决定需要在setter周围引发更改和更改事件.如果你暴露了一个字段,那么是时候进行重大的重写了.如果您使用了属性(或方法),那么您可以在那里添加逻辑.您突然失去了自动实现属性的好处,但您获得了在不破坏现有代码的情况下重构类的能力.
private string name;
public event NameChangingEventHandler NameChanging;
public event NameChangedEventHandler NameChanged;
public string Name
{
get { return name; }
set
{
OnNameChanging(/*...*/);
name = value;
OnNameChanged(/*...*/);
}
}
protected virtual void OnNameChanging(/*...*/) { }
protected virtual void OnNameChanged(/*...*/) { }
Run Code Online (Sandbox Code Playgroud)
所有这些都维护着您的公共API,并且不需要该类用户(代码的其余部分或使用您的API的外部开发人员)的工作.突破性变化并不总是可以避免,但避免直接访问字段是尝试确保不会发生变化的一个很好的步骤.自动实现的属性是一种快速,简便的方法.
(不相关:键入此功能时断电,我很高兴我的浏览器保存了大部分内容!)