243

私はDictionary<string, T>基本的に..任意の提案の Clone() を作成したい汎用辞書を持っています。

4

12 に答える 12

246

(注: 複製バージョンは有用な可能性がありますが、単純な浅いコピーの場合は、別の投稿で言及したコンストラクターの方が適しています。)

コピーの深さはどれくらいですか? また、使用している .NET のバージョンは何ですか? .NET 3.5 を使用している場合は、キー セレクターと要素セレクターの両方を指定する ToDictionary への LINQ 呼び出しが最も簡単な方法になると思います。

たとえば、値が浅いクローンであることを気にしない場合:

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

ICloneable を実装するように T を既に制約している場合:

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

(これらはテストされていませんが、動作するはずです。)

于 2008-09-26T13:53:05.577 に答える
199

さて、.NET 2.0 は次のように答えます。

値を複製する必要がない場合は、既存の IDictionary を取る Dictionary へのコンストラクター オーバーロードを使用できます。(比較子を既存の辞書の比較子として指定することもできます。)

値を複製する必要がある場合は、次のようなものを使用できます。

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()もちろん、それは適切に深いクローンであることにも依存しています。

于 2008-09-26T14:22:46.147 に答える
103
Dictionary<string, int> dictionary = new Dictionary<string, int>();

Dictionary<string, int> copy = new Dictionary<string, int>(dictionary);
于 2010-11-24T10:51:19.750 に答える
11

.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が、それ以外の一般的な実装はまったく実用的ではありません。

于 2008-09-26T15:09:44.100 に答える
7

いつでもシリアル化を使用できます。オブジェクトをシリアル化してから逆シリアル化できます。これにより、ディクショナリとその中のすべてのアイテムの詳細なコピーが得られます。[Serializable] としてマークされた任意のオブジェクトのディープ コピーを、特別なコードを記述することなく作成できるようになりました。

Binary Serialization を使用する 2 つの方法を次に示します。これらのメソッドを使用する場合は、単に呼び出すだけです

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;
}
于 2008-09-26T15:35:44.100 に答える
3

バイナリシリアル化の方法は正常に機能しますが、私のテストでは、クローンの非シリアル化の実装よりも10倍遅いことが示されました。でテストしましたDictionary<string , List<double>>

于 2009-09-30T16:07:58.447 に答える