收集初始化器的奇怪语法

时间:2015-12-21 22:43:37

标签: c#

假设我们有一个非常简单的类:

class ObjectList {
    public List<string> List1 { get; } = new List<string>();
    public List<string> List2 { get; set; }
}

我们想要创建这个类的实例:

ObjectList objectList = new ObjectList {
    List1 = { "asdf", "qwer" },
    List2 = new List<string> { "zxcv", "1234" }
};

所以,对于List2,没关系,使用&#34; =&#34;我们设置了财产。但是在List1的情况下,它看起来像我们设置属性,但实际上,我们假设在之前设置它,在这里我们只设置值。它与数组初始化非常相似:

string[] arr = { "val1", "val2" }

为什么C#在这里使用这种令人困惑的语法?

编辑: 我想我用C#6.0语法让很多观众感到困惑,但这不是重点。让我们使用旧的C#3.0和.net 2.0。并且让我们添加更多乐趣,并从头开始添加一些值(&#34; 1&#34;和#34; 2&#34;),如Jeff Mercado所建议:

class Program {
    static void Main(string[] args) {
        ObjectList objectList = new ObjectList {
            List1 = { "asdf", "qwer" },
        };
    }
}
class ObjectList {
    List<string> _List1 = new List<string>() { "1", "2" };
    public List<string> List1 {
        get {
            return _List1;
        }
    }
}

它显示了相同的奇怪语法。最后我列出了{&#34; 1&#34;,&#34; 2&#34;,&#34; asdf&#34;,&#34; qwer&#34; ,这更令人困惑。我可以期待这一点。

2 个答案:

答案 0 :(得分:3)

  

为什么C#在这里使用这种令人困惑的语法?

你说得对,它有点奇怪,但那是因为你混合了两个原则。正如一些评论已经指出的那样,当{ item1, items2 }左侧的项目是集合时,.Add(itemN)语法将转换为=次调用

因此,奇怪是

这一事实的结果
List<SomeClass> list = new List<SomeClass> { item1, item2 };
SomeClass[] array = { item1, item2 };

的处理方式不同。

另一部分是你的样本移动了new List<SomeClass>,但两种情况都存在。

答案 1 :(得分:2)

Eric Lippert

his answer to Why is an Add method required for { } initialization?给出了答案
  

由集合初始值设定项的典型使用场景推动的设计目标是在表达式语法中初始化现有集合类型,以便集合初始值设定项可以嵌入查询理解中或转换为表达式树。

     

其他每个场景的优先级都较低; 该功能完全存在,因为它有助于使LINQ工作

所以看起来,即使这个语法在创建只读集合时更有意义,它仍然被添加,因此它们可以按时提供LINQ。