为什么集合初始值设定项不能与表达式主体 属性 一起工作?
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 个元素(1
、2
、3
) .
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
.
我认为现在最好显示代码:
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 个元素(1
、2
、3
) .
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
.