जवाबों:
ठीक है, .NET 2.0 उत्तर:
यदि आपको मानों को क्लोन करने की आवश्यकता नहीं है, तो आप कंस्ट्रक्टर ओवरलोड का उपयोग उस शब्दकोश में कर सकते हैं जो एक मौजूदा IDEDIA लेता है। (आप तुलनाकर्ता को मौजूदा शब्दकोश के तुलनाकर्ता के रूप में भी निर्दिष्ट कर सकते हैं।)
यदि आपको मानों को क्लोन करने की आवश्यकता है, तो आप इस तरह से कुछ का उपयोग कर सकते हैं:
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()
विधि पर निर्भर है कि यह गहरा है या उथला है। मैंने इस आशय में एक नोट जोड़ा है।
ConcurrentDictionary
।
(ध्यान दें: हालांकि क्लोनिंग संस्करण संभावित रूप से उपयोगी है, एक साधारण उथले प्रतिलिपि के लिए जो कंस्ट्रक्टर मैंने दूसरे पोस्ट में उल्लेख किया है वह एक बेहतर विकल्प है।)
आप चाहते हैं कि प्रतिलिपि कितनी गहरी हो, और आप .NET के किस संस्करण का उपयोग कर रहे हैं? मुझे संदेह है कि कुंजी और तत्व चयनकर्ता दोनों को निर्दिष्ट करने के लिए एक LINQ टूबॉर्डर को कॉल करता है, यदि आप .NET 3.5 पर जा रहे हैं तो यह सबसे आसान तरीका होगा।
उदाहरण के लिए, यदि आपको उथले क्लोन होने का कोई मूल्य नहीं है:
var newDictionary = oldDictionary.ToDictionary(entry => entry.Key,
entry => entry.Value);
यदि आप पहले से ही IC को लागू करने के लिए T को विवश कर चुके हैं:
var newDictionary = oldDictionary.ToDictionary(entry => entry.Key,
entry => (T) entry.Value.Clone());
(वे अनछुए हैं, लेकिन काम करना चाहिए।)
Dictionary<string, int> dictionary = new Dictionary<string, int>();
Dictionary<string, int> copy = new Dictionary<string, int>(dictionary);
.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);
जैसा कि टॉमर वोल्बर्ग टिप्पणियों में वर्णन करते हैं, यह काम नहीं करता है यदि मूल्य प्रकार एक उत्परिवर्ती वर्ग है।
आप हमेशा क्रमबद्धता का उपयोग कर सकते हैं। आप उस वस्तु को क्रमबद्ध कर सकते हैं, फिर उसे निष्क्रिय कर सकते हैं। इससे आपको शब्दकोश और उसके अंदर की सभी वस्तुओं की गहरी प्रतिलिपि मिल जाएगी। अब आप किसी भी विशेष कोड को लिखे बिना किसी भी ऑब्जेक्ट की एक गहरी प्रतिलिपि बना सकते हैं, जिसे [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()
जब मैंने एक डिक्शनरी <string, string> को कॉपी करने की कोशिश की थी, तो इससे मुझे मदद मिली
Dictionary<string, string> dict2 = new Dictionary<string, string>(dict);
सौभाग्य
यदि कुंजी / मान 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;
}
पुरानी पोस्ट पर जवाब देने के बावजूद मुझे इसे इस प्रकार लपेटना उपयोगी लगा:
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;
}
}
entry.Value
मूल्य हो सकता है अभी तक एक और [उप] संग्रह।