![](/img/trans.png)
[英]Why can I use an anonymous collection initializer with a read-only auto-property while I can't use an object initializer
[英]Why can I use a collection initializer with private set access from another class?
考慮以下代碼:
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
添加項目的集合初始值設定項工作
Accodingly C# 3.0 cpesification,實現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();
}
}
來自C# 語言規范
應用集合初始值設定項的集合對象必須是實現
System.Collections.IEnumerable
的類型,否則會發生編譯時錯誤。 對於按順序指定的每個元素,集合初始值設定項調用目標對象上的 Add 方法,並使用元素初始值設定項的表達式列表作為參數列表,為每次調用應用正常的重載解析。 因此,集合對象必須包含適用於每個元素初始值設定項的Add
方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.