我有一个通用字典dictionary <string, T>,我想基本上使克隆()..任何建议。
当前回答
如果键/值是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;
}
其他回答
你总是可以使用序列化。你可以序列化对象,然后反序列化它。这将为您提供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;
}
(注意:虽然克隆版本可能很有用,但对于简单的浅复制,我在另一篇文章中提到的构造函数是更好的选择。)
你希望拷贝的深度是多少,你使用的是什么版本的。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;
}
在这种情况下,你有一个"object"的字典,object可以是(double, int,…或ComplexClass):
Dictionary<string, object> dictSrc { get; set; }
public class ComplexClass : ICloneable
{
private Point3D ...;
private Vector3D ....;
[...]
public object Clone()
{
ComplexClass clone = new ComplexClass();
clone = (ComplexClass)this.MemberwiseClone();
return clone;
}
}
dictSrc["toto"] = new ComplexClass()
dictSrc["tata"] = 12.3
...
dictDest = dictSrc.ToDictionary(entry => entry.Key,
entry => ((entry.Value is ICloneable) ? (entry.Value as ICloneable).Clone() : entry.Value) );
二进制序列化方法工作得很好,但在我的测试中,它比克隆的非序列化实现慢了10倍。在Dictionary<string, List<double>>上测试
推荐文章
- 实体框架核心:在上一个操作完成之前,在此上下文中开始的第二个操作
- 如何为构造函数定制Visual Studio的私有字段生成快捷方式?
- 如何使用JSON确保字符串是有效的JSON。网
- AppSettings从.config文件中获取值
- 通过HttpClient向REST API发布一个空体
- 如何检查IEnumerable是否为空或空?
- 自动化invokerrequired代码模式
- 在c#代码中设置WPF文本框的背景颜色
- 在c#中,什么是单子?
- c#和Java中的泛型有什么不同?和模板在c++ ?
- c#线程安全快速(est)计数器
- 如何将此foreach代码转换为Parallel.ForEach?
- 如何分裂()一个分隔字符串到一个列表<字符串>
- List、List<?>, List<T>, List<E>, List<Object>
- 如何转换列表<字符串>列表<int>?