请考虑以下代码:
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
属性,因此我认为无法设置其值。
答案 0 :(得分:12)
您的语句有效,因为集合初始化语法使用Add()
方法将项添加到集合中,而不是将成员设置为集合的新实例。基本上,您的代码相当于:
var order = new Order();
order.Items.Add(new OrderItem());
order.Items.Add(new OrderItem());
这很好,因为你只使用了getter方法。
答案 1 :(得分:6)
通过collection initializer调用Add
来添加项目
可以通过IEnumerable
方法初始化C#3.0 cpesification,实现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();
}
}
来自 C#语言规范
应用集合初始值设定项的集合对象 必须是实现
System.Collections.IEnumerable
或类型的类型 发生编译时错误。对于每个指定的元素按顺序, collection initializer用目标对象调用Add方法 元素初始值设定项的表达式列表作为参数列表, 为每次调用应用正常的重载决策。就这样 集合对象必须包含适用于每个的Add
方法 元素初始化器。