集合初始值设定项的奇怪语法

本文关键字:语法 集合 | 更新日期: 2023-09-27 18:27:49

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

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的情况下,使用"="设置属性是可以的。但在List1的例子中,看起来我们设置了属性,但实际上,我们假设在之前的某个地方设置它,而这里我们只设置值。它与数组初始化非常相似:

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

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

编辑:我想我用C#6.0语法混淆了很多观众,但这不是重点。让我们使用旧的好的C#3.0和.net 2.0。让我们也增加更多的乐趣,并从一开始就在列表中添加一些值("1"answers"2"),正如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;
        }
    }
}

它显示了同样奇怪的语法。最后,我列出了{"1"、"2"、"asdf"、"qwer"},这更令人困惑。我对这件事的期望越低。

集合初始值设定项的奇怪语法

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

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

所以奇怪的是

List<SomeClass> list = new List<SomeClass> { item1, item2 };
SomeClass[] array = { item1, item2 };

被区别对待。

另一部分是您的示例移动new List<SomeClass>,但在这两种情况下都存在。

Eric Lippert在回答"为什么{}初始化需要Add方法?

集合初始化器的典型使用场景所激发的设计目标是使表达式语法中现有集合类型的初始化成为可能,以便集合初始化器可以嵌入查询理解或转换为表达式树。

其他所有情况的优先级都较低该功能之所以存在,是因为它有助于LINQ工作

因此,即使这种语法在创建只读集合时更有意义,它还是被添加了进来,这样他们就可以按时交付LINQ了。