为何存在这种令人困惑的语法?

时间:2018-03-23 12:55:48

标签: c# collections object-initializers

我刚读过this question

如果我们有字典类型的属性:

public class Test
{
    public Dictionary<string, string> Dictionary { get; set; } = new Dictionary<string, string>
    {
        {"1", "1" },
        {"2", "2" },
    };
}

然后我们可以构造对象并为其添加值

 var test = new Test { Dictionary = { { "3", "3" } } };
 Console.WriteLine(test.Dictionary.Count); // 3

我不明白为什么存在如此混乱的语法来添加项目?在查看其他人的代码时,很容易将其与非常相似地混淆

 var test = new Test { Dictionary = new Dictionary<string, string> { { "3", "3" } } };
 Console.WriteLine(test.Dictionary.Count); // 1

如果可以遵循,我会更好(但不是):

var dictionary = new Dictionary<string, string> { { "1", "1" } };
...
// adding a new value
dictionary = { { "2" , "2"} }; // invalid expression term '{'

那么为什么需要这种形式的添加并存在呢?面试?

2 个答案:

答案 0 :(得分:3)

集合初始化程序语法只是使用对象初始值设定项初始化集合(包括字典)作为复杂对象模型的一部分的便捷方式。例如:

var model = new SomeModel {
   Name = "abc",
   Id = 42,
   SpecialMaps = {
       { "foo", "bar" },
       { "magic", "science" },
   }
};

如果你不喜欢它:就是不要使用它;但与手册.Add相当的是IMO更不优雅 - 很多东西都是自动处理的,比如只读一次属性。实际创建集合的较长版本的工作方式非常相似。

请注意,现在还有一个索引器变体:

var model = new SomeModel {
   Name = "abc",
   Id = 42,
   SpecialMaps = {
       ["foo"] = "bar",
       ["magic"] ="science",
   }
};

这非常相似,但不使用collection.Add(args);,而是使用collection[key] = value;。同样,如果它让你感到困惑或冒犯了你:不要使用它。

答案 1 :(得分:1)

Thing的构造函数创建StuffStuff的构造函数创建Foo列表

为例
var thing = new Thing();
thing.Stuff.Foo.Add(1);
thing.Stuff.Foo.Add(2);
thing.Stuff.Foo.Add(3);

现在您可以使用初始化程序将其简化为以下内容。

var thing = new Thing 
{
    Stuff.Foo = { 1, 2, 3 }
};

在嵌套时,您只能在不首先新建集合的情况下对集合使用此类型的初始化,因为在这种情况下集合可以存在,但在直接分配给变量时则不能。

最终语言设计师在看到他们认为可以简化的代码模式时,可能会添加这种类型的语法糖。