为什么我可以使用集合初始化器来访问另一个类的私有集合?
本文关键字:集合 另一个 访问 可以使 我可以 初始化 为什么 | 更新日期: 2023-09-27 18:03:19
考虑以下代码:
public sealed class Order
{
public Order()
{
Items = new List<OrderItem>();
}
public List<OrderItem> Items { get; private set; }
}
public sealed class OrderItem
{
}
这是Order
在另一个类中的初始化
var order = new Order
{
Items =
{
new OrderItem(),
new OrderItem()
}
};
你能解释一下它为什么有效吗?如您所见,Order
具有private set
属性,因此我认为不可能设置其值。
您的语句有效,因为集合初始化语法使用Add()
方法将项目添加到集合中,而不是将成员设置为集合的新实例。本质上,您的代码相当于:
var order = new Order();
order.Items.Add(new OrderItem());
order.Items.Add(new OrderItem());
这很好,因为您只使用getter方法。
简短回答:
它通过调用Add
的集合初始化器来添加项
长答:
根据c# 3.0规范,实现IEnumerable
并具有适当的Add
方法的对象可以通过Add
方法初始化。
Items
有public get
访问器和Items
, List<T>
实现了IEnumerable
并有Add
。以下是编译器如何看待你的代码
var order = new Order();
order.Items.Add(new OrderItem());
order.Items.Add(new OrderItem());
请注意,编译器不会使用List
实现IEnumerable
的信息,这是证明,不会抛出异常
public sealed class Order
{
public Order()
{
Items = new MyCollection();
}
public MyCollection Items { get; private set; }
}
public sealed class OrderItem
{
}
public class MyCollection : IEnumerable
{
private readonly List<OrderItem> _items = new List<OrderItem>();
public void Add(OrderItem item)
{
_items.Add(item);
}
public IEnumerator GetEnumerator()
{
throw new NotImplementedException();
}
}
应用集合初始化项的集合对象必须是实现
元素初始值设定项。System.Collections.IEnumerable
或发生编译时错误。对于按顺序指定的每个元素集合初始化器调用目标对象上的Add方法元素初始化式的表达式列表作为参数列表;对每个调用应用正常的重载解析。因此,集合对象必须包含一个适用的Add
方法