关于C#:我可以为Dictionary 条目使用集合初始值设定项吗?

Can I use a collection initializer for Dictionary<TKey, TValue> entries?

我要对下一位代码使用集合初始值设定项:

1
2
3
4
5
6
7
8
public Dictionary<int, string> GetNames()
{
    Dictionary<int, string> names = new Dictionary<int, string>();
    names.Add(1,"Adam");
    names.Add(2,"Bart");
    names.Add(3,"Charlie");
    return names;
}

所以通常应该是这样的:

1
2
3
4
5
return new Dictionary<int, string>
{
   1,"Adam",
   2,"Bart"
   ...

但正确的语法是什么?


1
2
3
4
5
var names = new Dictionary<int, string> {
  { 1,"Adam" },
  { 2,"Bart" },
  { 3,"Charlie" }
};


语法稍有不同:

1
2
3
4
5
Dictionary<int, string> names = new Dictionary<int, string>()
{
    { 1,"Adam" },
    { 2,"Bart" }
}

注意,您实际上是在添加值的元组。

另一个注意事项是:集合初始值设定项包含的参数基本上是针对编译时参数类型的任何add()函数的参数。也就是说,如果我有收藏:

1
2
3
4
5
6
7
8
class FooCollection : IEnumerable
{
    public void Add(int i) ...

    public void Add(string s) ...

    public void Add(double d) ...
}

以下代码完全合法:

1
var foos = new FooCollection() { 1, 2, 3.14,"Hello, world!" };


1
2
3
4
5
return new Dictionary<int, string>
{
   { 1,"Adam" },
   { 2,"Bart" },
   ...

这个问题被标记为c#-3.0,但为了完整性,我将提到C 6提供的新语法,以防您使用Visual Studio 2015(或Mono 4.0):

1
2
3
4
5
6
var dictionary = new Dictionary<int, string>
{
   [1] ="Adam",
   [2] ="Bart",
   [3] ="Charlie"
};

注意:其他答案中提到的旧语法仍然有效,如果您更喜欢的话。同样,为了完整性,这里是旧的语法:

1
2
3
4
5
6
var dictionary = new Dictionary<int, string>
{
   { 1,"Adam" },
   { 2,"Bart" },
   { 3,"Charlie" }
};

另一种很酷的做法是,无论使用哪种语法,如果愿意,都可以保留最后一个逗号,这样就更容易复制/粘贴其他行。例如,下面的编译很好:

1
2
3
4
5
6
var dictionary = new Dictionary<int, string>
{
   [1] ="Adam",
   [2] ="Bart",
   [3] ="Charlie",
};

如果您要寻找稍微不那么冗长的语法,可以创建Dictionary的子类(或您的类型),如下所示:

1
2
3
4
public class DebugKeyValueDict : Dictionary<string, object>
{

}

然后像这样初始化

1
2
3
4
5
6
var debugValues = new DebugKeyValueDict
                  {
                       {"Billing Address", billingAddress },
                       {"CC Last 4", card.GetLast4Digits() },
                       {"Response.Success", updateResponse.Success }
                  });

相当于

1
2
3
4
5
6
var debugValues = new Dictionary<string, object>
                  {
                       {"Billing Address", billingAddress },
                       {"CC Last 4", card.GetLast4Digits() },
                       {"Response.Success", updateResponse.Success }
                  });

好处是你能得到你想要的所有编译类型的东西,比如说

is DebugKeyValueDict代替is IDictionary

或者在以后更改键或值的类型。如果你在一个Razor CSHTML页面中做类似的事情,你会发现这样做会更好。

当然,除了不那么冗长之外,您还可以为这个类添加额外的方法,以满足您的需要。


在下面的代码示例中,Dictionary是用StudentName类型的实例初始化的。

1
2
3
4
5
6
  Dictionary<int, StudentName> students = new Dictionary<int, StudentName>()
  {
      { 111, new StudentName {FirstName="Sachin", LastName="Karnik", ID=211}},
      { 112, new StudentName {FirstName="Dina", LastName="Salimzianova", ID=317}},
      { 113, new StudentName {FirstName="Andy", LastName="Ruth", ID=198}}
  };

来自MSDN


是的,我们可以在字典中使用集合初始值设定项。-

1
2
3
4
5
Dictionary<int,string> dict = new Dictionary<int,string>();  
            dict.Add(1,"Mohan");  
            dict.Add(2,"Kishor");  
            dict.Add(3,"Pankaj");  
            dict.Add(4,"Jeetu");

我们可以如下初始化它。

1
2
3
4
5
6
7
8
9
Dictionary<int,string> dict = new Dictionary<int,string>  
            {  

                {1,"Mohan" },  
                {2,"Kishor" },  
                {3,"Pankaj" },  
                {4,"Jeetu" }  

            };