为什么集合初始值设定项不能与表达式主体 属性 一起工作?

Why collection initializer is not working together with expression body property?

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

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

Ints2 => new List<int>();Ints2 { get { return new List<int>(); } } 的缩写。每次读取 属性 时,它 returns 一个新的空列表。您已经有了解决方法:您的第一个表单将列表存储在一个字段中。

每次当您访问您的 Ints2 属性 它 returns 新的 List<int> 实例。

这是因为您如何定义 属性 Int2。虽然它确实是一个 getter,但它总是返回一个新列表。 Int1 是一个只读自动 属性 所以它总是返回相同的列表。为下面的 class 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 的所有突变都丢失了,因为列表总是新的。

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

这一行意味着 属性 返回的支持字段是用 new List<int>() 初始化的。

Collection initializer 所做的是为每个元素调用 Add 方法,因此 Ints1 将有 3 个元素(123) .


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

表达式 bodied 表示您正在定义 getter 的正文,如下所示:

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

每次调用 Ints2 都会返回一个新实例,这就是为什么 Count 属性 returns 0.