我有一个通用字典dictionary <string, T>,我想基本上使克隆()..任何建议。


当前回答

我将计算T是否为值或引用类型。如果T是值类型,我将使用Dictionary的构造函数,如果T是引用类型,我将确保T继承自ICloneable。

它会给

    private static IDictionary<string, T> Copy<T>(this IDictionary<string, T> dict)
         where T : ICloneable
    {
        if (typeof(T).IsValueType)
        {
            return new Dictionary<string, T>(dict);
        }
        else
        {
            var copy = new Dictionary<string, T>();
            foreach (var pair in dict)
            {
                copy[pair.Key] = pair.Value;
            }
            return copy;
        }
    }

其他回答

对我来说最好的方法是:

Dictionary<int, int> copy= new Dictionary<int, int>(yourListOrDictionary);

(注意:虽然克隆版本可能很有用,但对于简单的浅复制,我在另一篇文章中提到的构造函数是更好的选择。)

你希望拷贝的深度是多少,你使用的是什么版本的。net ?如果你使用的是。net 3.5,我认为对ToDictionary的LINQ调用,同时指定键和元素选择器将是最简单的方法。

例如,如果你不介意这个值是一个浅克隆:

var newDictionary = oldDictionary.ToDictionary(entry => entry.Key,
                                               entry => entry.Value);

如果你已经限制了T来实现ICloneable:

var newDictionary = oldDictionary.ToDictionary(entry => entry.Key, 
                                               entry => (T) entry.Value.Clone());

(这些方法未经测试,但应该有效。)

这里是克隆字典的另一种方法,假设你知道做“正确”的事情,只要处理任何隐藏在“T”(a.k.a)后面的东西。“对象”)。

internal static Dictionary<string, object> Clone(Dictionary<string, object> dictIn) 
    {
        Dictionary<string, object> dictOut = new Dictionary<string, object>();
    
        IDictionaryEnumerator enumMyDictionary = dictIn.GetEnumerator();
        while (enumMyDictionary.MoveNext())
        {
            string strKey = (string)enumMyDictionary.Key;
            object oValue = enumMyDictionary.Value;
            dictOut.Add(strKey, oValue);
        }
    
        return dictOut; 
    }

你总是可以使用序列化。你可以序列化对象,然后反序列化它。这将为您提供Dictionary及其所有条目的深层副本。现在您可以创建任何标记为[Serializable]的对象的深度副本,而无需编写任何特殊代码。

这里有两种将使用二进制序列化的方法。如果使用这些方法,只需调用

object deepcopy = FromBinary(ToBinary(yourDictionary));

public Byte[] ToBinary()
{
  MemoryStream ms = null;
  Byte[] byteArray = null;
  try
  {
    BinaryFormatter serializer = new BinaryFormatter();
    ms = new MemoryStream();
    serializer.Serialize(ms, this);
    byteArray = ms.ToArray();
  }
  catch (Exception unexpected)
  {
    Trace.Fail(unexpected.Message);
    throw;
  }
  finally
  {
    if (ms != null)
      ms.Close();
  }
  return byteArray;
}

public object FromBinary(Byte[] buffer)
{
  MemoryStream ms = null;
  object deserializedObject = null;

  try
  {
    BinaryFormatter serializer = new BinaryFormatter();
    ms = new MemoryStream();
    ms.Write(buffer, 0, buffer.Length);
    ms.Position = 0;
    deserializedObject = serializer.Deserialize(ms);
  }
  finally
  {
    if (ms != null)
      ms.Close();
  }
  return deserializedObject;
}
Dictionary<string, int> dictionary = new Dictionary<string, int>();

Dictionary<string, int> copy = new Dictionary<string, int>(dictionary);