【问题标题】:What's the fastest way to copy the values and keys from one dictionary into another in C#?在 C# 中将值和键从一个字典复制到另一个字典的最快方法是什么?
【发布时间】:2010-09-10 00:58:43
【问题描述】:

似乎没有 dictionary.AddRange() 方法。有谁知道在不使用 foreach 循环的情况下将项目复制到另一个字典的更好方法。

我正在使用 System.Collections.Generic.Dictionary。这适用于 .NET 2.0。

【问题讨论】:

    标签: c# dictionary copy foreach


    【解决方案1】:

    Dictionary 构造函数接受另一个 Dictionary

    您必须将其转换为IDictionary,但有一个Add() 重载需要KeyValuePair<TKey, TValue>。不过,您仍在使用 foreach。

    【讨论】:

    • 感谢您的回答,但两本词典中都有我需要复制的项目。
    【解决方案2】:

    for/foreach 循环没有任何问题。无论如何,这只是假设的 AddRange 方法。

    我唯一需要担心的是内存分配行为,因为添加大量条目可能会导致多次重新分配和重新散列。没有办法将现有字典的容量增加给定的数量。您最好为当前的两个字典分配一个容量足够的新字典,但您仍然需要一个循环来加载其中至少一个。

    【讨论】:

      【解决方案3】:
      var Animal = new Dictionary<string, string>();
      

      可以将现有的动物字典传递给构造函数。

      Dictionary<string, string> NewAnimals = new Dictionary<string, string>(Animal);
      

      【讨论】:

        【解决方案4】:

        为了好玩,我为字典创建了这个扩展方法。这应该尽可能地进行深层复制。

        public static Dictionary<TKey, TValue> DeepCopy<TKey,TValue>(this Dictionary<TKey, TValue> dictionary)
                {
                    Dictionary<TKey, TValue> d2 = new Dictionary<TKey, TValue>();
        
                    bool keyIsCloneable = default(TKey) is ICloneable;
                    bool valueIsCloneable = default(TValue) is ICloneable;
        
                    foreach (KeyValuePair<TKey, TValue> kvp in dictionary)
                    {
                        TKey key = default(TKey);
                        TValue value = default(TValue);
                        if (keyIsCloneable)
                        {
                            key = (TKey)((ICloneable)(kvp.Key)).Clone();
                        }
        
                        else
                        {
                            key = kvp.Key;
                        }
        
                        if (valueIsCloneable)
                        {
                            value = (TValue)((ICloneable)(kvp.Value)).Clone();
                        }
        
                        else
                        {
                            value = kvp.Value;
                        }
        
                        d2.Add(key, value);
                    }
        
                    return d2;
                }
        

        【讨论】:

          【解决方案5】:

          如果您正在处理两个现有对象,您可能会使用 CopyTo 方法获得一些好处:http://msdn.microsoft.com/en-us/library/cc645053.aspx

          使用其他集合(接收者)的Add方法来吸收它们。

          【讨论】:

          • 我找不到需要数组的 Dictionary 的 Add 方法?
          【解决方案6】:

          我不明白,为什么不使用 Dictionary( Dictionary )(如 ageektrapped 所建议的那样)。

          您要执行浅拷贝还是深拷贝? (也就是说,两个字典都指向新字典中每个对象的相同引用或新副本?)

          如果你想创建一个new Dictionary 指向new 对象,我认为唯一的方法就是通过一个foreach。 p>

          【讨论】:

          • 浅拷贝没问题。我有两个要在方法中填充的字典,我想在方法结束时将第二个较小的字典复制到第一个字典中。我需要在方法的生命周期中将它们分开,因为它们的含义不同。
          【解决方案7】:

          对于原始类型字典:

          public void runIntDictionary()
          {
              Dictionary<int, int> myIntegerDict = new Dictionary<int, int>() { { 0, 0 }, { 1, 1 }, { 2, 2 } };
              Dictionary<int, int> cloneIntegerDict = new Dictionary<int, int>();
              cloneIntegerDict = myIntegerDict.Select(x => x.Key).ToList().ToDictionary<int, int>(x => x, y => myIntegerDict[y]);
          }
          

          或使用实现 ICloneable 的对象:

          public void runObjectDictionary()
          {
              Dictionary<int, number> myDict = new Dictionary<int, number>() { { 3, new number(3) }, { 4, new number(4) }, { 5, new number(5) } };
              Dictionary<int, number> cloneDict = new Dictionary<int, number>();
              cloneDict = myDict.Select(x => x.Key).ToList().ToDictionary<int, number>(x => x, y => myDict[y].Clone());
          }
          
          public class number : ICloneable
          {
              public number()
              {
              }
              public number(int newNumber)
              {
                  nr = newnumber;
              }
              public int nr;
          
              public object Clone()
              {
                  return new number() { nr = nr };
              }
              public override string ToString()
              {
                  return nr.ToString();
              }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-01-03
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多