正如其他人所说,不同之处_names
在于检索属性后字段的状态。
情况1
get { return _names ?? (_names = new List<string>()); }
如果_names
为 null,List<string>
则将创建并分配一个新的。在此之后,每次检索该属性Names
都将返回刚刚创建的列表。
案例2
get { return _names ?? new List<string>(); }
如果_names
为空,List<string>
将返回一个新的。与案例 1 相比,它不会被分配给任何东西。这意味着每次检索时Names
,都会创建并返回一个新列表。
话虽如此,您应该非常小心这段代码的两个版本。在 a in 中赋值get
不一定是件好事。懒惰地实例化属性值很方便,并且在您是唯一使用该类的人的情况下可能是可以接受的,但它的风格很差。您班级以外的任何用户都不会期望 aget
设置任何内容……这就是set
属性的一部分。_names
从长远来看,在默认构造函数中返回并实例化它总是会更好。然后很清楚代码在做什么,并且您获得了保证的非空属性值。
对于第二种情况,您最好返回 null 并允许用户处理它。考虑以下情况,其中items
是一个大型对象集合,每个对象都包含您的属性Names
,并且无论出于何种原因,其中Names
始终为空:
foreach (var item in items.Where(x => x.Names != null)) {
Console.WriteLine(String.Join(", ", item.Names));
}
如果您只是返回 null,则将跳过整个块。但是,由于您每次都返回一个新列表,因此您不仅要运行整个循环并且基本上什么都不做,而且每次迭代都会实例化一个新列表!在某些条件下,这可能会变得非常昂贵。