如何在C#中向字典中添加多个值?

45

如果我不想多次调用 ".Add()",那么向字典中添加多个值的最佳方法是什么?

编辑:我想在初始化后填充它!字典中已经有一些值了!

因此,不是

    myDictionary.Add("a", "b");
    myDictionary.Add("f", "v");
    myDictionary.Add("s", "d");
    myDictionary.Add("r", "m");
    ...
我想做类似这样的事情。
 myDictionary.Add(["a","b"], ["f","v"],["s","d"]);

有办法这样做吗?


1
http://msdn.microsoft.com/en-us/library/bb531208.aspx - Marc
可能是 C#中合并字典的重复问题 - Mike Dimmick
10个回答

53

你可以使用花括号来进行初始化,但这只适用于初始化时:

var myDictionary = new Dictionary<string, string>
{
    {"a", "b"},
    {"f", "v"},
    {"s", "d"},
    {"r", "m"}
};

这被称为 "集合初始化",适用于任何 ICollection<T>(有关字典,请参见此链接;对于其他任何集合类型,请参见此链接)。实际上,它适用于实现了 IEnumerable 并包含 Add 方法的任何对象类型:

class Foo : IEnumerable
{
    public void Add<T1, T2, T3>(T1 t1, T2 t2, T3 t3) { }
    // ...
}

Foo foo = new Foo
{
    {1, 2, 3},
    {2, 3, 4}
};

基本上,这只是用于重复调用 Add 方法的语法糖。初始化后,有几种方法可以做到这一点,其中之一是手动调用Add方法:

var myDictionary = new Dictionary<string, string>
    {
        {"a", "b"},
        {"f", "v"}
    };

var anotherDictionary = new Dictionary<string, string>
    {
        {"s", "d"},
        {"r", "m"}
    };

// Merge anotherDictionary into myDictionary, which may throw
// (as usually) on duplicate keys
foreach (var keyValuePair in anotherDictionary)
{
    myDictionary.Add(keyValuePair.Key, keyValuePair.Value);
}

或者作为扩展方法:

static class DictionaryExtensions
{
    public static void Add<TKey, TValue>(this IDictionary<TKey, TValue> target, IDictionary<TKey, TValue> source)
    {
        if (source == null) throw new ArgumentNullException("source");
        if (target == null) throw new ArgumentNullException("target");

        foreach (var keyValuePair in source)
        {
            target.Add(keyValuePair.Key, keyValuePair.Value);
        }
    }
}

var myDictionary = new Dictionary<string, string>
    {
        {"a", "b"},
        {"f", "v"}
    };

myDictionary.Add(new Dictionary<string, string>
    {
        {"s", "d"},
        {"r", "m"}
    });

1
初始化后没有填充的方法吗? - LocalHorst
3
这只是另一个与“Add”结合使用的for/foreach循环,这只是添加方法的语法糖。对于Dictionary<TKey, TValue>来说,并不存在像“AddRange”这样的东西,因为无论如何都需要对键进行哈希处理。 - Caramiriel

7
这并不是一个重复的问题,但你可能想要的是有一个Dictionary.AddRange()方法。为什么它不存在呢?请参阅为什么Dictionary没有AddRange?
“对于一个关联容器来说,范围并没有真正的意义。”
但编写自己的.AddRange()方法到Dictionary类可能是个好主意。本质上它将是一系列.Add()调用的循环。

4
他可能想要的是.AddMultiple().AddMany(),或者其他类似的方法,也就是说,“range”这个词暗示着整数索引,而这并不是他想要的。 - Virus721

5
尽管这个问题已经得到了回答,但我很好奇是否可以将集合初始化器的语法应用到已经初始化的字典中,而不需要创建/覆盖一个第二个字典以合并并丢弃。
你可以使用(滥用?)集合初始化器来在创建后向现有字典添加值范围。如何操作?通过创建一个辅助类来实现:
public class AddRangeTo<TKey, TValue> : IEnumerable
{
    private readonly IDictionary<TKey, TValue> WrappedDictionary;

    public AddRangeTo(IDictionary<TKey, TValue> wrappedDictionary)
    {
        this.WrappedDictionary = wrappedDictionary;
    }

    public void Add(TKey key, TValue value)
    {
        this.WrappedDictionary.Add(key, value);
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        throw new NotSupportedException();
    }
}

使用方法:

var myDictionary = new Dictionary<string, string>();

new AddRangeTo<string, string>(myDictionary)
{
    {"a", "b"},
    {"f", "v"},
    {"s", "d"},
    {"r", "m"}
};

请注意,此方法允许您使用类似的语法向已初始化的字典添加条目。有点不好的是需要重复写 <string, string> 泛型,但 C# 6.0 不再需要这样做了。(注:在 C# 6 中会像 new AddRangeTo(myDictionary) 一样)。但是要注意,这个语法可能会产生意外的副作用,可能会令人困惑,因此我并不是非常推荐使用。除非您确实经常使用这种方法来使您的内部代码更易于使用和维护。

4
您可以在初始化时像其他答案一样进行操作,或者您可以将其与此技巧相结合:
Dictionary<string, string> myDictionary = new Dictionary<string, string>();
Dictionary<string, string> secondDictionary = new Dictionary<string, string>()
{ 
    {"1", "a"}, 
    {"2", "b"} 
};
myDictionary = myDictionary.Union(secondDictionary)
                           .ToDictionary(kvp => kvp.Key, kvp => kvp.Value);

您需要确保没有重复的键,否则会出现异常(但这与Add方法相同)。


1
“Union”将导致另一个不再是字典的“IEnumerable<T>”。这也可能包含重复的键,因为“KeyValuePair<T>”没有基于键实现相等性/哈希码(假设它创建了一个字典)。 - Caramiriel
添加了 ToDictionary 并备注了重复键。 - Raidri

3
您可以这样做:
var myDict = new Dictionary<string, string>() 
{
    {"a", "aa"},
    {"b", "bb"},
    {"c", "cc"},
    {"d", "dd"}
};

2
这可以通过使用扩展方法在主代码路径之外完成,从而使您能够减少其发生的混乱。
public static class DictionaryExtensions
{
  public static IDictionary<TKey,TValue> AddRange<TKey,TValue>(
               this IDictionary<TKey,TValue> source,
               params  KeyValuePair<TKey,TValue>[] items)
  {
    foreach (var keyValuePair in items)
    {
      source.Add(keyValuePair.Key, keyValuePair.Value);
    }
    return source;
  }
}

0

这本来是一个简单的谷歌搜索:http://msdn.microsoft.com/en-us/library/bb531208.aspx。 无论如何...这是代码:

Dictionary<string, string> myDictionary = new Dictionary<string, string>()
{
    { 'a', 'b' },
    { 'c', 'd' },
    { 'e', 'f' }
};

当然,你也可以编写一个循环或其他迭代方式来遍历你的值,并每次调用 .add() 方法。

0
可以在初始化时做到这一点:
new Dictionary<string, string> { {"a","b"}, {"f","v"},{"s","d"} }

这被称为集合初始化器。 当您想要向已经存在的字典中添加多个项目时,可以编写一个方法。


-1

我有一个完美的初始化示例。假设你想把罗马数字转换为整数。你会收到一个包含罗马数字的字符串,需要一种方法来映射每个字符的意义。在C#中,你可以使用一个包含字符和它们对应整数的字典。

var map = new Dictionary<char, int>{
        {'M',1000},
        {'D',500},
        {'C',100},
        {'L',50},
        {'X',10},
        {'V',5},
        {'I',1}
    };

-2

myDictionary = new Dictionary() { {"a", 2) }, { "b", 3 }, };

我的字典 = 新的字典() { {"a", 2) }, { "b", 3 }, };

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接