web-dev-qa-db-ja.com

List <MyObject>の正しいクローンを作成するにはどうすればよいですか?

可能性のある複製:
C#でジェネリックリストを複製するにはどうすればよいですか?

List<MyObject> a1 = new List<MyObject>();

var new1 = a1;

変更した場合a1、次にnew1も変更されます。

だから私の質問はa1のクローンを正しく作成する方法ですか?

14
Developer

これはリストの各項目をCloneしませんが、新しいリストを作成します

var new1 = new List<MyObject>(a1);

リスト内の各アイテムのクローンを作成する場合は、ICloneableMyObjectに実装できます

var new1 = new List<MyObject>(a1.Select(x => x.Clone()));

編集:少しわかりやすくするために、両方ともリストから要素をコピーしますa1を新しいリストに追加します。新しいMyObjectsを使用するか、元のバージョンを保持するかを決定する必要があるだけです。 MyObjectのクローンを作成する場合は、通常ICloneableを使用してクローンを作成する方法が必要です。

34
aqwert

または、次のようにすることもできます。

public static class CloneClass
{
    /// <summary>
    /// Clones a object via shallow copy
    /// </summary>
    /// <typeparam name="T">Object Type to Clone</typeparam>
    /// <param name="obj">Object to Clone</param>
    /// <returns>New Object reference</returns>
    public static T CloneObject<T>(this T obj) where T : class
    {
        if (obj == null) return null;
        System.Reflection.MethodInfo inst = obj.GetType().GetMethod("MemberwiseClone",
            System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
        if (inst != null)
            return (T)inst.Invoke(obj, null);
        else
            return null;
    }
}

次に、次のように使用します。

var new1 = CloneClass.CloneObject<List<<MyObject>>(a1);
4
MAckerman

オブジェクトの浅いコピーと深いコピーのどちらであるかは明確でないため、一般的な方法は Clone の使用を避けることだと思います。

詳細はこちら: http://blogs.msdn.com/b/brada/archive/2004/05/03/125427.aspx

かなり一般的な解決策は、BinaryFormatterクラスを使用してオブジェクトをシリアライズ/シリアライズして新しいインスタンスを返すことですが、クラスはシリアライズ可能でなければならないことに注意してください。

https://stackoverflow.com/a/1213649/1212407

上記を前提として、次のことができます。

var clonedList = originaList.DeepClone();
1
Jesse