我可以为Dictionary <TKey,TValue>条目使用集合初始值设定项吗?

Ger*_*nck 94 .net c# generics collections c#-3.0

我想为下一段代码使用集合初始值设定项:

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;
}
Run Code Online (Sandbox Code Playgroud)

通常它应该是这样的:

return new Dictionary<int, string>
{ 
   1, "Adam",
   2, "Bart"
   ...
Run Code Online (Sandbox Code Playgroud)

但是这个的正确语法是什么?

bru*_*nde 156

var names = new Dictionary<int, string> {
  { 1, "Adam" },
  { 2, "Bart" },
  { 3, "Charlie" }
};
Run Code Online (Sandbox Code Playgroud)

  • @Nyerguds - 我猜你有权得到你的意见,但是如果你立即初始化你的变量,那么使用`var`和重复自己`SomeType obj = new SomeType ...`之间几乎没有区别.而且由于你不能在没有立即初始化的情况下声明`var obj;`,我只是没有看到问题.真的,我正在努力学习,但我无法理解你的立场. (4认同)

Ant*_*lev 35

语法略有不同:

Dictionary<int, string> names = new Dictionary<int, string>()
{
    { 1, "Adam" },
    { 2, "Bart" }
}
Run Code Online (Sandbox Code Playgroud)

请注意,您正在有效地添加值元组.

作为旁注:集合初始值设定项包含的参数基本上是任何Add()函数的参数,该函数对于编译时参数类型而言非常方便.也就是说,如果我有一个集合:

class FooCollection : IEnumerable
{
    public void Add(int i) ...

    public void Add(string s) ...

    public void Add(double d) ...
}
Run Code Online (Sandbox Code Playgroud)

以下代码完全合法:

var foos = new FooCollection() { 1, 2, 3.14, "Hello, world!" };
Run Code Online (Sandbox Code Playgroud)

  • @Shimmy:为什么这么重要?关键是它将与_any_类一起使用,该类实现`IEnumerable <T>`并且具有`Add`方法.如果`Add`方法需要_3_参数,那么括号中需要3个对象. (2认同)

ybo*_*ybo 11

return new Dictionary<int, string>
{ 
   { 1, "Adam" },
   { 2, "Bart" },
   ...
Run Code Online (Sandbox Code Playgroud)


Nat*_*ook 10

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

var dictionary = new Dictionary<int, string>
{
   [1] = "Adam",
   [2] = "Bart",
   [3] = "Charlie"
};
Run Code Online (Sandbox Code Playgroud)

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

var dictionary = new Dictionary<int, string>
{
   { 1, "Adam" },
   { 2, "Bart" },
   { 3, "Charlie" }
};
Run Code Online (Sandbox Code Playgroud)

另一种很酷的事情是,无论使用哪种语法,您都可以保留最后一个逗号(如果您愿意),这样可以更轻松地复制/粘贴其他行.例如,以下编译就好了:

var dictionary = new Dictionary<int, string>
{
   [1] = "Adam",
   [2] = "Bart",
   [3] = "Charlie",
};
Run Code Online (Sandbox Code Playgroud)


Sim*_*ver 5

如果你正在寻找稍微冗长的语法,你可以创建一个子类Dictionary<string, object>(或者你的类型),如下所示:

public class DebugKeyValueDict : Dictionary<string, object>
{

}
Run Code Online (Sandbox Code Playgroud)

然后就像这样初始化

var debugValues = new DebugKeyValueDict
                  {
                       { "Billing Address", billingAddress }, 
                       { "CC Last 4", card.GetLast4Digits() },
                       { "Response.Success", updateResponse.Success }
                  });
Run Code Online (Sandbox Code Playgroud)

这相当于

var debugValues = new Dictionary<string, object>
                  {
                       { "Billing Address", billingAddress }, 
                       { "CC Last 4", card.GetLast4Digits() },
                       { "Response.Success", updateResponse.Success }
                  });
Run Code Online (Sandbox Code Playgroud)

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

is DebugKeyValueDict 代替 is IDictionary<string, object>

或者在以后更改密钥或值的类型.如果你在剃刀cshtml页面中做这样的事情,那么看起来好多了.

除了更简洁之外,您当然可以为此类添加额外的方法,以满足您的任何需求.