我认为现在最好显示代码:
class Foo
{
public ICollection<int> Ints1 { get; } = new List<int>();
public ICollection<int> Ints2 => new List<int>();
}
class Program
{
private static void Main(string[] args)
{
var foo = new Foo
{
Ints1 = { 1, 2, 3 },
Ints2 = { 4, 5, 6 }
};
foreach (var i in foo.Ints1)
Console.WriteLine(i);
foreach (var i in foo.Ints2)
Console.WriteLine(i);
}
}
显然Main
方法应该打印1,2,3,4,5,6,但它只打印1,2,3。初始化后foo.Ints2.Count
等于零。为什么呢?
答案 0 :(得分:5)
这是因为你如何定义属性Int2。虽然它确实是一个吸气剂,但它总是会返回一个新列表。 Int1是一个只读的自动属性,所以它总是返回相同的列表。下面的类Foo删除了等效的编译器魔术代码:
class Foo
{
private readonly ICollection<int> ints1 = new List<int>();
public ICollection<int> Ints1 { get { return this.ints1; } }
public ICollection<int> Ints2 { get { return new List<int>(); } }
}
正如您所看到的,Ints2的所有变异都会丢失,因为列表总是新的。
答案 1 :(得分:2)
Ints2 => new List<int>();
是Ints2 { get { return new List<int>(); } }
的缩写。每次读取属性时,它都会返回一个新的空列表。您已经有了修复:您的第一个表单将列表存储在一个字段中。
答案 2 :(得分:2)
每次访问Ints2
属性时,都会返回新的List<int>
实例。
答案 3 :(得分:1)
public ICollection<int> Ints1 { get; } = new List<int>();
此行表示属性返回的支持字段已使用new List<int>()
初始化。
Collection初始化程序为每个元素调用Add
方法,因此Ints1
将包含3个元素(1
,2
,3
)。< / p>
public ICollection<int> Ints2 => new List<int>();
表达身体意味着您正在定义getter
的正文,如下所示:
public ICollection<int> Ints2 => new List<int>();
{
get
{
return new List<int>();
}
}
每次调用Ints2
时都会返回一个新实例,这就是Count
属性返回0
的原因。