Why can I use a collection initializer with private set access from another class?
.net, c#
Solution
Short answer:
It works thru collection initializer which calls `Add` to add items
Long answer:
Accodingly C# 3.0 cpesification, object which implement `IEnumerable` and has appropiate `Add` method can be initialised thru the `Add` method.
`Items` has `public get` accessor and `Items` it's a `List<T>` which implements `IEnumerable` and has `Add`. Here's how the compiler sees your code
var order = new Order();
order.Items.Add(new OrderItem());
order.Items.Add(new OrderItem());
Please note, the compiler doesn't use info that the `List` implements `IEnumerable`, here's the proof, no exception will be thrown
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();
}
}
from C# Language Specification
The collection object to which a collection initializer is applied must be of a type that implements `System.Collections.IEnumerable` or a compile-time error occurs. For each specified element in order, the collection initializer invokes an Add method on the target object with the expression list of the element initializer as argument list, applying normal overload resolution for each invocation. Thus, the collection object must contain an applicable `Add` method for each element initializer.
Problem
Consider the following code: ``` public sealed class Order { public Order() { Items = new List<OrderItem>(); } public List<OrderItem> Items { get; private set; } } public sealed class OrderItem { } ``` and here's `Order` initialization in another class. ``` var order = new Order { Items = { new OrderItem(), new OrderItem() } }; ``` Could you explain why it works? As you see the `Order` has `private set` property, so I thought it would be impossible to set its value.