哪个更正确,为什么?

时间:2011-03-25 16:13:56

标签: c# poco

哪种更好的实施还是没有区别?

1

public class Simple
{
    public IList<string> Entries { get; private set; }

    public Simple()
    {
        Entries = new List<string>();
    }
}

或2.

public class Simple
{
    private readonly IList<string> entries = new List<string>();
    public IList<string> Entries { get { return entries; } }
}

9 个答案:

答案 0 :(得分:2)

我会假设你的意思是第二个版本:

public class Simple
{
    private readonly IList<string> entries = new List<string>();
    public IList<string> Entries { get { return entries; } }
}

请注意,我已将entries变量设为只读。

如果这就是你的意思,因为你不需要在类中的任何地方重新分配变量(除了可能在构造函数中),那么我认为这比自动属性版本更好。 / p>

它显示了明确的意图,即意味着是只读的 - 而自动属性只表明它是对外部世界的只读 。有人(也许你)可能最终会在类中的中更改自动属性的值,忘记原始设计是为了只读属性。

(当然,我们并没有真正谈论完全不变性,因为任何人都可以在列表中添加或删除条目。)

如果您真的希望能够更改类中的属性值,请务必使用第一个版本。

表达了对readonly字段版本的偏好,实际上我发现自己使用了自动属性,因为它的读写代码较少。每次我做完它都会感觉很脏。理想情况下,我想要一种创建只读自动实现的属性的方法,该属性只能在构造函数中设置,就像只读字段一样。 (该属性将由只读字段支持,并且setter调用将直接编译为字段分配。)我还没有听说过任何实际发生这种事情的计划。

答案 1 :(得分:1)

没有真正的实际区别(#2不会编译,你需要省略设置者)。

只要你不需要getter中的逻辑,并且不需要直接访问该字段,那就是风格问题。

我更喜欢自动属性版本,因为(我觉得)它稍微简单一点,并在需要时重构一个带有支持字段的属性。

答案 2 :(得分:1)

如果您将列表存储在字段中,则可以将该字段标记为readonly,以确保您不会更改该类中的字段。

public class Simple
{
    private readonly IList<string> entries = new List<string>();
    public IList<string> Entries { get { return entries; } }
}

答案 3 :(得分:0)

选项#2首先不会编译。

除此之外,在选项#2中,您可以完全省略set访问者。例如,这将使PropertyInfo.CanWrite返回false

答案 4 :(得分:0)

选项#1更好,因为在第二个你也可能错过了readonly关键字。

答案 5 :(得分:0)

我更喜欢第二种方法。这样,在构造函数运行之前,列表可供您使用。优点是,如果你要添加更多的类构造函数等,你不必担心/记得一遍又一遍地新增列表。

答案 6 :(得分:0)

使用对您来说更具可读性(或者,如果您为具有一致风格的项目编写代码,请保持一致)。

它们几乎相同(我假设您打算在第二个示例中声明实例变量private并省略setter),但有一点需要注意的是,无法将自动实现的属性标记为{{1 }}。不幸的是,这是一个非常简洁的功能,似乎没有尽可能多地使用它。

在任何情况下,就任何其他课程而言,它们都是相同的,所以如果你决定改变主意,这是一个非常微不足道的改变。因此,选择有效的方法并且不要过多 - 这不是一个单一风格真正成为“既定标准”的领域。

就我个人而言,只有当我有一个readonly变量时才会使用第二个,否则我会使用第一个(它的输入更少)。嘿Anders,自动实现只读属性怎么样?

修改

编辑过的问题有一个更简单的答案:如果字段为readonly,请将其标记为readonly。唯一的方法是第二种方式。

不区分readonly属性不是主要的罪或任何东西,但它肯定不如区分它们(甚至可能有助于防止一些错误)。

答案 7 :(得分:0)

在您公开的API和代码中的语义中都没有真正的区别(好的,第一个允许您稍后覆盖Entries变量,这可能是您不想要的)。 / p>

大部分区别在于语法只是一种品味问题。

答案 8 :(得分:0)

无论如何,第一个编译成IL的等价物:

public class Simple{    
  private IList<string> entries;

  public IList<string> Entries { 
    get { return entries; }
  } 

  public Simple() {
    entries= new List<string>();    
  }
}

因此,它们之间的唯一区别在于,您的第一个允许实例在需要时将引用更改为其他集合,而另一个则不允许。

这将是第二种方法的等同物:

public class Simple{    
  private readonly IList<string> entries;

  public IList<string> Entries { 
    get { return entries; }
  } 

  public Simple() {
    entries= new List<string>();    
  }
}