为何C#存在这种易混淆的Dictionary集合初始化语法?
解答:C#中集合初始化器的两种用法差异与设计初衷
我当初刚接触C#的时候也被这两种写法搞混过,其实核心是要区分集合初始化器的两种使用场景:
1. 成员访问式集合初始化(添加元素)
当你写:
var test = new Test { Dictionary = { { "3", "3" } } };
这里的{ { "3", "3" } }并不是在给Dictionary属性赋值,而是一种语法糖——编译器会把它转换成对现有集合的Add方法调用。也就是说,这段代码等价于:
var test = new Test(); test.Dictionary.Add("3", "3");
因为你的Test类已经初始化了Dictionary属性(自带两个元素),所以调用Add后Count自然变成3。
2. 赋值式集合初始化(替换实例)
而当你写:
var test = new Test { Dictionary = new Dictionary<string, string> { { "3", "3" } } };
这里的new Dictionary<string, string> { { "3", "3" } }是先创建一个全新的字典实例(里面只有一个元素),然后把这个实例赋值给Test的Dictionary属性,直接替换掉原来的那个初始化好的字典,所以Count是1。
为什么要设计这种易混淆的添加语法?
这种语法的设计初衷是为了让对象初始化更连贯、简洁。想象一下,如果你的Test类有多个属性,其中包括集合类型,你可以在初始化Test对象的同时,直接给它的集合属性填充元素,不用分多步操作:
var test = new Test { Name = "SampleTest", Description = "A test class with dictionary", Dictionary = { { "1", "First" }, { "2", "Second" } } };
这样代码更紧凑,可读性也更强,不用先实例化Test,再逐个给属性赋值、给集合加元素。
为什么不能直接用dictionary = { { "2", "2" } };?
这种单独的写法编译器是不认可的,因为集合初始化器语法只有两种合法场景:
- 直接初始化集合实例时,比如
var dict = new Dictionary<string, string> { { "2", "2" } }; - 在对象初始化器内部,对已有集合属性进行元素添加(也就是第一种场景)
单独写dictionary = { { "2", "2" } };时,编译器不知道你要创建什么类型的集合,也无法确定你是要添加元素还是替换实例,所以语法不允许。如果要给已有字典加元素,直接调用dictionary.Add("2", "2");就好,批量添加的话可以用循环或者自己封装扩展方法。
内容的提问来源于stack exchange,提问作者Sinatr
相关产品推荐
相关产品推荐

