我有一个通用字典 Dictionary<string, T>
,我想要创建一个它的副本(Clone()).. 有什么建议吗?
我有一个通用字典 Dictionary<string, T>
,我想要创建一个它的副本(Clone()).. 有什么建议吗?
var newDictionary = oldDictionary.ToDictionary(entry => entry.Key,
entry => entry.Value);
var newDictionary = oldDictionary.ToDictionary(entry => entry.Key,
entry => (T) entry.Value.Clone());
好的,.NET 2.0 的答案如下:
如果您不需要克隆值,则可以使用 Dictionary 的构造函数重载,该函数接受现有的 IDictionary。(您也可以将比较器指定为现有字典的比较器。)
如果您需要克隆值,则可以使用以下代码:
public static Dictionary<TKey, TValue> CloneDictionaryCloningValues<TKey, TValue>
(Dictionary<TKey, TValue> original) where TValue : ICloneable
{
Dictionary<TKey, TValue> ret = new Dictionary<TKey, TValue>(original.Count,
original.Comparer);
foreach (KeyValuePair<TKey, TValue> entry in original)
{
ret.Add(entry.Key, (TValue) entry.Value.Clone());
}
return ret;
}
当然,这取决于TValue.Clone()
也是一个合适的深层克隆。
Clone()
方法决定。我已经添加了一条相关的注释。 - Jon SkeetConcurrentDictionary
。 - Jon SkeetDictionary<string, int> dictionary = new Dictionary<string, int>();
Dictionary<string, int> copy = new Dictionary<string, int>(dictionary);
当我尝试深度复制一个Dictionary<string, string>时,这就是帮助我的方法。
Dictionary<string, string> dict2 = new Dictionary<string, string>(dict);
祝你好运
对于 .NET 2.0,您可以实现一个继承自 Dictionary
并实现 ICloneable
接口的类。
public class CloneableDictionary<TKey, TValue> : Dictionary<TKey, TValue> where TValue : ICloneable
{
public IDictionary<TKey, TValue> Clone()
{
CloneableDictionary<TKey, TValue> clone = new CloneableDictionary<TKey, TValue>();
foreach (KeyValuePair<TKey, TValue> pair in this)
{
clone.Add(pair.Key, (TValue)pair.Value.Clone());
}
return clone;
}
}
您可以通过调用Clone
方法来简单地克隆字典。当然,此实现要求字典的值类型实现ICloneable
接口,否则通用实现根本不可行。
这对我来说很好用
// assuming this fills the List
List<Dictionary<string, string>> obj = this.getData();
List<Dictionary<string, string>> objCopy = new List<Dictionary<string, string>>(obj);
您可以使用序列化。您可以对对象进行序列化,然后进行反序列化。这将为您提供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<int, int> copy= new Dictionary<int, int>(yourListOrDictionary);
二进制序列化方法可以正常工作,但在我的测试中,它显示比非序列化克隆的实现慢了10倍。 在 Dictionary<string, List<double>>
上进行了测试。
ToBinary()
中,Serialize()
方法使用 this
而不是 yourDictionary
进行调用。然后在 FromBinary()
中,byte[] 首先手动复制到 MemStream 中,但实际上可以直接提供给其构造函数。 - Jupiter如果键/值是 ICloneable,请尝试这个:
public static Dictionary<K,V> CloneDictionary<K,V>(Dictionary<K,V> dict) where K : ICloneable where V : ICloneable
{
Dictionary<K, V> newDict = null;
if (dict != null)
{
// If the key and value are value types, just use copy constructor.
if (((typeof(K).IsValueType || typeof(K) == typeof(string)) &&
(typeof(V).IsValueType) || typeof(V) == typeof(string)))
{
newDict = new Dictionary<K, V>(dict);
}
else // prepare to clone key or value or both
{
newDict = new Dictionary<K, V>();
foreach (KeyValuePair<K, V> kvp in dict)
{
K key;
if (typeof(K).IsValueType || typeof(K) == typeof(string))
{
key = kvp.Key;
}
else
{
key = (K)kvp.Key.Clone();
}
V value;
if (typeof(V).IsValueType || typeof(V) == typeof(string))
{
value = kvp.Value;
}
else
{
value = (V)kvp.Value.Clone();
}
newDict[key] = value;
}
}
}
return newDict;
}