উত্তর:
ঠিক আছে, .NET 2.0 উত্তর:
আপনার যদি মানগুলি ক্লোন করার প্রয়োজন না হয় তবে আপনি অভিধানে কন্সট্রাক্টর ওভারলোড ব্যবহার করতে পারেন যা একটি বিদ্যমান আইডিকোরিয়াম গ্রহণ করে। (আপনি বিদ্যমান অভিধানের তুলনাকারী হিসাবেও তুলনাকারী নির্দিষ্ট করতে পারেন))
আপনি যদি না মান ক্লোন করতে, আপনি ভালো কিছু ব্যবহার করতে পারেন:
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
।
(দ্রষ্টব্য: যদিও ক্লোনিং সংস্করণটি সম্ভাব্যভাবে কার্যকর, তবে একটি সাধারণ অগভীর অনুলিপিটির জন্য আমি অন্য পোস্টে যে কনস্ট্রাক্টরটি উল্লেখ করেছি এটি একটি ভাল বিকল্প)
আপনি অনুলিপিটি কতটা গভীর হতে চান এবং আপনি নেট নেট এর কোন সংস্করণ ব্যবহার করছেন? আমি সন্দেহ করি যে টিনডোরের কাছে একটি লিনকিউ কল, কী এবং উপাদান নির্বাচক উভয়ই নির্দিষ্ট করে, আপনি যদি নেট .৩.৫ ব্যবহার করেন তবে যাওয়ার সবচেয়ে সহজ উপায় হবে।
উদাহরণস্বরূপ, যদি আপনি মানটিকে অগভীর ক্লোন হিসাবে মানা না করেন:
var newDictionary = oldDictionary.ToDictionary(entry => entry.Key,
entry => entry.Value);
আপনি যদি ইতিমধ্যে ICloneable বাস্তবায়ন করতে টি সীমাবদ্ধ করে থাকেন:
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);
টোমর ওলবার্গ মন্তব্যগুলিতে যেমন বর্ণনা করেছেন, মানের ধরণটি পরিবর্তনীয় শ্রেণীর হলে এটি কাজ করে না।
আপনি সর্বদা সিরিয়ালাইজেশন ব্যবহার করতে পারেন। আপনি অবজেক্টটি সিরিয়ালাইজ করতে পারেন তারপরে এটিকে ডিসরিয়ালাইজ করতে পারেন। এটি আপনাকে অভিধানের একটি অনুলিপি এবং এর ভিতরে থাকা সমস্ত আইটেম দেবে। এখন আপনি কোনও বিশেষ কোড না লিখে যে কোনও অবজেক্টের [সিরিয়ালাইজযোগ্য] হিসাবে চিহ্নিত হওয়া একটি গভীর অনুলিপি তৈরি করতে পারেন।
এখানে দুটি পদ্ধতি রয়েছে যা বাইনারি সিরিয়ালাইজেশন ব্যবহার করবে। আপনি যদি এই পদ্ধতিগুলি ব্যবহার করেন তবে কেবল কল করুন
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;
}
বাইনারি সিরিয়ালাইজেশন পদ্ধতিটি দুর্দান্ত কাজ করে তবে আমার পরীক্ষাগুলিতে এটি ক্লোনটির অ-সিরিয়ালাইজেশন প্রয়োগের চেয়ে 10x ধীর হয়ে গেছে। এটি পরীক্ষিতDictionary<string , List<double>>
ToBinary()
Serialize()
this
yourDictionary
FromBinary()
আমি যখন একটি অভিধান <স্ট্রিং, স্ট্রিং> গভীরভাবে অনুলিপি করার চেষ্টা করছিলাম তখন এটিই আমাকে সাহায্য করেছিল
Dictionary<string, string> dict2 = new Dictionary<string, string>(dict);
শুভকামনা
কী / মানগুলি আইকনলোনযোগ্য হয় তবে এটি চেষ্টা করুন:
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
মান হতে পারে আরেকটি [সাব] সংগ্রহ।