Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么我可以使用具有来自另一个类的私有集访问权限的集合初始值设定项?_C#_.net - Fatal编程技术网

C# 为什么我可以使用具有来自另一个类的私有集访问权限的集合初始值设定项?

C# 为什么我可以使用具有来自另一个类的私有集访问权限的集合初始值设定项?,c#,.net,C#,.net,考虑以下代码: public sealed class Order { public Order() { Items = new List<OrderItem>(); } public List<OrderItem> Items { get; private set; } } public sealed class OrderItem { } 你能解释一下它为什么有效吗?正如您看到的那样,Order具有private

考虑以下代码:

public sealed class Order
{
    public Order()
    {
        Items = new List<OrderItem>();
    }

    public List<OrderItem> Items { get; private set; }
}

public sealed class 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
方法初始化

项目
具有
公共获取
访问器和
项目
它是一个
列表
,它实现了
IEnumerable
并具有
添加
。以下是编译器如何看待代码

var order = new Order();
order.Items.Add(new OrderItem());
order.Items.Add(new OrderItem());
请注意,编译器没有使用
列表
实现的信息
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();
    }
}
公共密封类命令
{
公共秩序()
{
Items=新的MyCollection();
}
公共MyCollection项{get;private set;}
}
公共密封类OrderItem
{
}
公共类MyCollection:IEnumerable
{
私有只读列表_items=new List();
公共作废添加(订单项)
{
_项目。添加(项目);
}
公共IEnumerator GetEnumerator()
{
抛出新的NotImplementedException();
}
}
C#语言规范

应用集合初始值设定项的集合对象 必须是实现
System.Collections.IEnumerable
或 发生编译时错误。对于顺序中的每个指定元素 集合初始值设定项使用 元素初始值设定项的表达式列表作为参数列表, 为每个调用应用正常重载解析。因此 集合对象必须包含适用于每个对象的
Add
方法 元素初始值设定项


奇怪的是,它需要实现
IEnumerable
,因为集合初始值设定项没有使用它。@Magnus:当时这是一个有争议的决定。我们对使用
Add
方法的类型进行了广泛的研究,发现有两大类:可变集合类和数学类。没有人希望进入一种可以使用集合初始值设定项进行计算的情况。区别在于集合几乎都实现了
IEnumerable
,而数学类型没有实现,所以我们选择它作为我们的shibboleth。集合初始值设定项不创建集合的实例。从构造函数中删除
new
,您将得到一个异常。在构造函数中添加一些项,它们将在另一个类中初始化后保留。哇,我从来没有意识到这在嵌套集合中是可能的。谢谢你的邀请!
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();
    }
}