为什么集合初始值设定项不与表达式body属性一起使用?

时间:2016-04-27 15:36:52

标签: c# c#-6.0

我认为现在最好显示代码:

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等于零。为什么呢?

4 个答案:

答案 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个元素(123)。< / p>

public ICollection<int> Ints2 => new List<int>();

表达身体意味着您正在定义getter的正文,如下所示:

public ICollection<int> Ints2 => new List<int>();
{
    get 
    {
        return new List<int>();
    }
}

每次调用Ints2时都会返回一个新实例,这就是Count属性返回0的原因。