0

私はこのカスタムクラスオブジェクトのリストを持っています:

List<URL> URLs = new List<URL>();

コピーをスタックにプッシュしようとしています:

Stack<List<URL>> undo = new Stack<List<URL>>();

List<URL> temp = new List<URL>();
temp.AddRange(new List<URL>(URLs));
undo.Push(temp);

これで、元の(URL)リストからオブジェクトを削除するたびに、スタック(temp)にあるオブジェクトですべてOKになります。しかし、元の(URL)のオブジェクト内のリストからリスト要素を削除すると、スタック上にあるそのオブジェクトのリストのコピーで同じ要素が消えます。

そのオブジェクト内のリスト要素を削除するのと同じ方法で、URLからオブジェクトを削除します。なぜこれが起こっているのか誰かが知っていますか?

4

5 に答える 5

1

これは、Listが基本的に配列、つまり参照型であるためです。それらはお互いの参照のみを持ちます。

拡張メソッドを使用してディープコピーを作成する

public static class ExtensionMethod
{  
    public static T DeepClone<T>(this T element)
    { 
        MemoryStream m = new MemoryStream();
        BinaryFormatter b = new BinaryFormatter();
        b.Serialize(m, element);
        m.Position = 0;
        return (T)b.Deserialize(m);
    }
}

そして、あなたがこのようにあなたのURLクラスを宣言することを確認してください

[Serializable]
public class URL
{
   //..... Your Class
}

そしてそれを次のように呼びます

temp.AddRange(URLs.DeepClone().ToList());
于 2012-04-28T06:57:37.387 に答える
0

クローンを作成する必要があります

static class Extensions
{
        public static IList<T> Clone<T>(this IList<T> listToClone) where T: ICloneable
        {
                return listToClone.Select(item => (T)item.Clone()).ToList();
        }
}
于 2012-04-28T07:01:56.800 に答える
0

リストまたはスタックは、それに含まれるオブジェクトへの参照のみを保持します。両方のリストには、同じオブジェクトへの参照が含まれています。したがって、一方のリストから到達したオブジェクトを変更すると、それはもう一方のリストから到達したオブジェクトと同じになります。

@simply denisが示唆しているように、2番目のリストを作成するときにオブジェクトのクローンを作成して、各リストにオブジェクトの独自のコピーを含めることができます。

別の解決策は、不変オブジェクトを使用することです。たとえばstring、.NETのクラスは不変です。一度作成した文字列は変更できません。すべての文字列操作ルーチンは、新しい文字列を返します。不変の型は、操作によって新しいインスタンスが自動的に作成されるため、この種の問題を効果的に防ぎます。

于 2012-04-28T07:02:31.577 に答える
0

これは、リストの浅いコピーを作成しているためです。URL同じオブジェクトへの参照を持つ2つのリストを取得します。

(実際には2つの浅いコピーを作成していることに注意してくださいnew List<URL>(URLs)。中間のコピーを作成し、そこから読み取ってから破棄するだけです。)

ディープコピーが必要なURL場合は、コピーの新しいインスタンスを作成する必要があります。クラスで何を実装したかはわかりませんURLが、基本的には次のようになります。

List<URL> temp = new List<URL>(URLs.Select(u => u.Clone()));
于 2012-04-28T07:04:42.773 に答える
0

これは、undoのURLオブジェクトが、URLのURLオブジェクトと同じオブジェクトを参照しているためです。したがって、1つを変更すると、もう1つに影響します。あなたがする必要があるのは、URLオブジェクトのディープコピーを作成することです。ディープコピーを作成する方法は、実際にはURLクラスの実装によって異なります。一般的な方法は次のとおりです。.NET(具体的にはC#)でオブジェクトのディープコピーをどのように実行しますか?

URLただし、オブジェクトのクローンを作成するためのより良い/より効率的な方法がある可能性があることに注意してください。最初にクラスの実装を示す必要があります。

于 2012-04-28T07:07:02.100 に答える