为什么我可以将集合初始化程序与其他类的私有集访问一起使用?

时间:2014-05-14 20:27:33

标签: c# .net

请考虑以下代码:

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属性,因此我认为无法设置其值。

2 个答案:

答案 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方法的对象。

Itemspublic 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方法   元素初始化器。