我看到很多的,做这个C#类示例代码:
public class Point {
public int x { get; set; }
public int y { get; set; }
}
或者说,在旧的代码,有一个明确的私人后盾值,没有新的自动实现的属性是相同的:
public class Point {
private int _x;
private int _y;
public int x {
get { return _x; }
set { _x = value; }
}
public int y {
get { return _y; }
set { _y = value; }
}
}
我的问题是为什么。 是否有这样做的上方和正使这些成员的公共领域,如下面之间的功能差异?
public class Point {
public int x;
public int y;
}
需要明确的是,我明白了getter和setter的值时,你需要做的基础数据的一些翻译。 但是,在你刚刚通过传递值的情况下,似乎不必要的冗长。
Answer 1:
我倾向于同意(这似乎是不必要的冗长),虽然这一直是一个问题,我们的团队还没有解决,所以我们的编码标准仍然坚持所有类的详细属性。
杰夫阿特伍德几年前处理这个。 他回顾指出,最重要的一点是,从一个领域转变为一个属性是一个重大更改您的代码; 任何消耗它必须重新编译与新的类接口的工作,因此,如果你的控制范围之外的事情在消费类,你可能有问题。
Answer 2:
它也更简单将其改为稍后:
public int x { get; private set; }
Answer 3:
它封装了这些成员的设置和访问。 如果从一段时间以来的代码开发人员需要改变逻辑当一个成员被访问或设置它可以在不改变类的合同来完成。
Answer 4:
我们的想法是,即使底层的数据结构需要改变,公共接口的类不会有改变。
C#有时可以区别对待属性和变量。 例如,你不能传递特性ref或out参数 。 所以,如果你需要改变的数据结构由于某种原因,你用公共变量,现在你需要使用属性,你的界面将不得不改变,现在访问属性x代码可能不再编译就像它时,它是变量X:
Point pt = new Point();
if(Int32.TryParse(userInput, out pt.x))
{
Console.WriteLine("x = {0}", pt.x);
Console.WriteLine("x must be a public variable! Otherwise, this won't compile.");
}
从一开始就使用属性避免了这一点,因为你需要在不破坏客户端代码,你可以随意尽可能多的调整底层的实现。
Answer 5:
setter和getter使您可以添加额外的抽象层,并在纯OOP,你总是应该通过他们所提供给外界的接口访问的对象...
考虑下面的代码,这将节省你在asp.net并没有通过getter和setter方法提供抽象的层次,将是不可能的:
class SomeControl
{
private string _SomeProperty ;
public string SomeProperty
{
if ( _SomeProperty == null )
return (string)Session [ "SomeProperty" ] ;
else
return _SomeProperty ;
}
}
Answer 6:
由于汽车实施干将花费的财产和实际的私有存储变量相同的名称。 你怎么可以改变它的未来? 我觉得这样说的一点是,使用实施的领域,而不是汽车,这样就可以如果万一你需要添加逻辑来getter和setter在将来改变它。
例如:
public string x { get; set; }
并且,例如,你已经使用XA很多次,你不想破坏你的代码。
如何改变汽车的getter setter方法......例如用于制定者只允许设置一个有效的电话号码格式...你如何改变代码,以便只有类是要改变?
我的想法是添加一个新的私有变量,并添加相同的X getter和setter。
private string _x;
public string x {
get {return x};
set {
if (Datetime.TryParse(value)) {
_x = value;
}
};
}
这是您使它灵活是什么意思?
Answer 7:
此外,当谈到约束力和序列化被认为是改变公众成员的影响。 这两个往往依靠公共属性来检索和设置值。
Answer 8:
此外,你可以把getter和setter断点,但你不能在多个领域。
Answer 9:
AFAIK生成的CIL接口是不同的。 如果更改一个公共成员的属性,你正在改变它的公共接口,而且需要重建使用该类的每个文件。 这是没有必要的,如果你只改变getter和setter的实现。
Answer 10:
也许只是让公共领域你可以带你到一个更贫血的域模型 。
亲切的问候
Answer 11:
还值得一提的是,你不能让汽车性能只读的,你不能在线初始化它们。 这两件事情,我想在未来的.NET释放看到的,但我相信你能做到无论是在.NET 4.0。
唯一的时候,我用的背场的属性,这些天,当我的类实现INotifyPropertyChanged,我需要当一个属性更改为火OnPropertyChanged事件。
另外,在这些情况下,我直接设置支持字段的值时,在从构造函数(不需要尝试和火OnPropertyChangedEvent(这将是空在这个时候无论如何)获得通过,其他地方我用的是物业本身。
Answer 12:
你永远不知道你可能不需要数据的一些翻译版本。 如果隐藏了你的会员你是准备了。 你的类不会通知用户如果添加翻译自接口保持不变。
Answer 13:
最大difrence是,如果有的话你改变你的内部结构,你仍然可以保持getter和setter原样,改变其内在的逻辑,而不伤害你的API的用户。
Answer 14:
If you have to change how you get x and y in this case, you could just add the properties later. This is what I find most confusing. If you use public member variables, you can easily change that to a property later on, and use private variables called _x and _y if you need to store the value internally.
Answer 15:
getter和setter方法,原则上不好(他们是一个坏的气味OO - 我站短说,他们是一个反模式,因为他们真的是必要的,有时的)。
没有,在技术上是没有区别的,当我真的想分享的对象,这些天的访问,我偶尔把它公开最终代替添加一个getter。
getter和setter方法被“卖”的方式是,你可能需要知道有人得到一个值或改变一个 - 它才有意义与原语。
类似的DAO,DTO的和显示对象属性包对象被排除在该规则,因为这些都不是在Word对象的一个真正的“OO设计”之意的对象。 (你不觉得“传递信息”的一个DAO,它只是属性/值对的桩)。
文章来源: Auto-implemented getters and setters vs. public fields