我看到很多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的价值。但是,如果你只是通过这些价值观,它似乎毫无疑问地冗长。

有帮助吗?

解决方案

我倾向于同意(它似乎不必要地冗长),虽然这是我们的团队尚未解决的问题,因此我们的编码标准仍然坚持所有类别的详细属性。

几年前,

Jeff Atwood 处理了这个问题。他回顾性地指出的最重要的一点是,从一个地方变为一个地产是一个更改;任何消耗它的东西都必须重新编译才能使用新的类接口,所以如果你控制之外的任何东西都在消耗你的类,你可能会遇到问题。

其他提示

稍后将其更改为更简单:

public int x { get; private set; }

它封装了这些成员的设置和访问。如果从现在起一段时间,代码的开发人员需要在访问或设置成员时更改逻辑,则可以在不更改类的合同的情况下完成。

这个想法是,即使底层数据结构需要更改,也不必更改类的公共接口。

C#可以不同地处理属性和变量。例如,您无法将属性作为参考或输出参数传递。因此,如果由于某种原因需要更改数据结构并且您正在使用公共变量并且现在需要使用属性,那么您的接口将不得不更改,现在代码访问属性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.");
}

从一开始就使用属性可以避免这种情况,您可以随意调整底层实现,而不会破坏客户端代码。

使用Setter和Getter可以添加额外的抽象层,在纯OOP中,您应该始终通过它们提供给外界的界面来访问对象...

考虑一下这段代码,它会将你保存在asp.net中,如果没有setter和getter提供的抽象级别,它就不可能实现:

class SomeControl
{

private string _SomeProperty  ;
public string SomeProperty 
{
  if ( _SomeProperty == null ) 
   return (string)Session [ "SomeProperty" ] ;
 else 
   return _SomeProperty ; 
}
}

由于自动实现的getter对属性和实际的私有存储变量使用相同的名称。你怎么能在将来改变它?我认为要说的是使用auto实现而不是字段,以便将来可以更改它,以防万一你需要为getter和setter添加逻辑。

例如:

public string x { get; set; }

例如,您已经多次使用x并且您不想破坏您的代码。

如何更改自动吸气器设定器...例如,对于设定器,您只允许设置有效的电话号码格式...如何更改代码以便只更改类?

我的想法是添加一个新的私有变量并添加相同的x getter和setter。

private string _x;

public string x { 
    get {return x}; 
    set {
        if (Datetime.TryParse(value)) {
            _x = value;
        }
    }; 
}

这是灵活的意思吗?

还需要考虑的是绑定和序列化时公共成员的更改效果。这两者通常都依赖于公共属性来检索和设置值。

此外,您可以在getter和setter上添加断点,但不能在字段上。

AFAIK生成的CIL界面不同。如果将公共成员更改为属性,则需要更改其公共接口,并且需要重新构建使用该类的每个文件。如果您只更改getter和setter的实现,则不需要这样做。

也许只是公开字段你可以引导你更多贫血领域模型

亲切的问候

还值得注意的是,您无法进行自动属性Readonly,也无法内联初始化它们。这些都是我希望在将来的.NET版本中看到的东西,但我相信你在.NET 4.0中都不会这样做。

这些天我唯一使用带有属性的支持字段的时候是我的类实现了INotifyPropertyChanged并且我需要在更改属性时触发OnPropertyChanged事件。

同样在这些情况下,当从构造函数传入值时,我直接设置了支持字段(无需尝试激活OnPropertyChangedEvent(此时无论如何都是NULL),在我使用该属性本身的任何其他地方。 / p>

您永远不知道以后是否需要对数据进行一些翻译。如果你隐藏你的成员,你已经准备好了。由于界面保持不变,因此您的班级用户不会注意到您是否添加了翻译。

最大的不同之处在于,如果你改变了内部结构,你仍然可以按原样维护getter和setter,改变它们的内部逻辑而不会伤害你的API用户。

如果在这种情况下你必须改变获得x和y的方式,你可以稍后添加属性。这是我发现最令人困惑的事情。如果使用公共成员变量,则可以在以后轻松将其更改为属性,并在需要在内部存储值时使用名为_x和_y的私有变量。

塞特尔和吸气剂原则上是不好的(它们是一种糟糕的OO气味 - 我不会说它们是反模式的,因为它们有时是必要的)。

不,技术上没有区别,当我真的想分享对象的访问权限时,我偶尔会将其公之于众,而不是添加一个getter。

主持人和吸气者的方式是“已售出”。是你可能需要知道某人正在获得一个价值或改变一个价值 - 这只适用于基元。

此规则不包括DAO,DTO和显示对象等属性包对象,因为这些对象不是真实“OO设计”中的对象。对象的含义。 (您没有想到“将消息传递给DAO”,它只是一堆属性/值对。)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top