objeto example control como clonar c# generics collections clone

c# - example - como clonar un objeto



¿Cuál es la mejor forma de clonar/copiar en profundidad un diccionario genérico.NET<string, T>? (10)

Tengo un Diccionario de diccionario genérico que me gustaría esencialmente hacer un Clon () de ... cualquier sugerencia.


(Nota: aunque la versión de clonación es potencialmente útil, para una simple copia poco profunda, el constructor que menciono en la otra publicación es una mejor opción).

¿Qué tan profundo quieres que sea la copia y qué versión de .NET estás usando? Sospecho que una llamada LINQ a ToDictionary, especificando tanto la tecla como el selector de elementos, será la forma más fácil de hacerlo si está usando .NET 3.5.

Por ejemplo, si no te importa que el valor sea un clon superficial:

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

Si ya ha restringido T para implementar ICloneable:

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

(Esos no han sido probados, pero deberían funcionar).


De acuerdo, el .NET 2.0 responde:

Si no necesita clonar los valores, puede usar la sobrecarga del constructor para Dictionary que toma un IDictionary existente. (También puede especificar el comparador como el comparador del diccionario existente).

Si necesita clonar los valores, puede usar algo como esto:

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; }

Eso depende de que TValue.Clone() sea ​​un clon adecuadamente profundo, por supuesto.


El método de serialización binaria funciona bien, pero en mis pruebas demostró ser 10 veces más lento que una implementación de clonación sin serialización. Probado en Dictionary<string , List<double>>


Esto funciona bien para mi

// assuming this fills the List List<Dictionary<string, string>> obj = this.getData(); List<Dictionary<string, string>> objCopy = new List<Dictionary<string, string>>(obj);


Intenta esto si key / values ​​son 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; }


La mejor manera para mí es esta:

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


Para .NET 2.0, podría implementar una clase que herede de Dictionary e implemente 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; } }

A continuación, puede clonar el diccionario simplemente llamando al método Clone . Por supuesto, esta implementación requiere que el tipo de valor del diccionario implemente ICloneable , pero de lo contrario una implementación genérica no es práctica en absoluto.


Siempre puedes usar la serialización. Puedes serializar el objeto y luego deserializarlo. Eso le dará una copia profunda del diccionario y todos los elementos dentro de él. Ahora puede crear una copia profunda de cualquier objeto que esté marcado como [Serializable] sin escribir ningún código especial.

Aquí hay dos métodos que utilizarán la serialización binaria. Si usa estos métodos, simplemente llame

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; }


Sin embargo, en respuesta a la publicación anterior, me pareció útil incluirlo de la siguiente manera:

using System; using System.Collections.Generic; public class DeepCopy { public static Dictionary<T1, T2> CloneKeys<T1, T2>(Dictionary<T1, T2> dict) where T1 : ICloneable { if (dict == null) return null; Dictionary<T1, T2> ret = new Dictionary<T1, T2>(); foreach (var e in dict) ret[(T1)e.Key.Clone()] = e.Value; return ret; } public static Dictionary<T1, T2> CloneValues<T1, T2>(Dictionary<T1, T2> dict) where T2 : ICloneable { if (dict == null) return null; Dictionary<T1, T2> ret = new Dictionary<T1, T2>(); foreach (var e in dict) ret[e.Key] = (T2)(e.Value.Clone()); return ret; } public static Dictionary<T1, T2> Clone<T1, T2>(Dictionary<T1, T2> dict) where T1 : ICloneable where T2 : ICloneable { if (dict == null) return null; Dictionary<T1, T2> ret = new Dictionary<T1, T2>(); foreach (var e in dict) ret[(T1)e.Key.Clone()] = (T2)(e.Value.Clone()); return ret; } }


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