2

位置とサイズを持つオブジェクトのリストを取得し、それらをキャンバスにプロットする WPF フォームがあります。現在、オブジェクトの位置に加えられたすべての変更を破棄し、フォームが読み込まれたときに取得された元のコレクションに戻る元に戻すボタンを実装しようとしています。

現時点では、フォームのロード時にデータベースにアクセスし、表示する必要があるすべてのオブジェクトを取得してから、返されたリストを 2 つの個別のコレクションに割り当てます。発生する問題は、2 つのコレクションが実際には元のコレクションへのポインターであり、一方が変更されるたびに、変更が 2 番目のコレクションに反映されることです。

オブジェクトのリストをコピーして、1 つのコレクションに加えられた変更がセカンダリ コレクションに影響しないようにすることはできますか?

これまでのところ、単純に代入演算子を使用して、ソース コレクションを関数に渡し、byvalリストの各要素をスクロールして 2 番目のコレクションに手動で追加し、linq を使用して元のリストからすべてのオブジェクトを取得し、結果をプッシュしようとしました。別の一時リストに追加し、2 番目のコレクションを一時リストに割り当てます。

問題を複雑にしすぎているように感じますが、グーグルで出会ったほとんどすべての場所で、この動作は設計によるものであると言われており、これは理解していますが、これはかなり一般的な考えのようです。

4

4 に答える 4

2

オブジェクトの「ディープ」コピーを作成するために以前に使用した関数を次に示します。

Public Function DeepCopy(ByVal ObjectToCopy As Object) As Object

    Using mem as New MemoryStream

        Dim bf As New BinaryFormatter
        bf.Serialize(mem, ObjectToCopy)

        mem.Seek(0, SeekOrigin.Begin)

        Return bf.Deserialize(mem)

    End Using

End Function

これは、他のいくつかの回答と比較して低レベルのアプローチですが、任意のオブジェクトをディープ コピーできます。配列のディープコピーが必要なあなたと同様の状況で、私はそれをうまく使用しました。

于 2012-05-24T21:33:32.687 に答える
0

var copy = list.ToList();リストのコピーを取得するために使用すると言った、削除された別の回答がありました。これには次の注意事項があります。どちらのリストも同じオブジェクトを参照するため、これらのオブジェクトへの変更は両方のリストに反映されます。リスト内のオブジェクトの順序のみを変更する限り、このソリューションは完全に実行可能です。

于 2012-05-24T20:53:30.627 に答える
0

新しいリストを作成し、list1 の項目のコピーをそれに追加する必要があります。オブジェクトの初期化を使用してこれを行うことができます。

Dim list2 = (From item in list1
             Select New ItemType With {.Property1 = item.Property1, .Property2 = item.Property2}.ToList()

別の方法は、コピー コンストラクターを ItemType に追加することです。

Public Sub New(item as ItemType)
    Me.Property1 = item.Property1
    Me.Property2 = item.Property2
End Sub

リストのコピーは次のように単純化できます

Dim list2 = (From item in list1
             Select New ItemType(item)}.ToList()

ItemType のプロパティのいずれかが参照である場合は、これらのオブジェクトのコピーも作成する必要があることに注意してください。(これはディープ コピーと呼ばれます)

于 2012-05-24T20:57:26.830 に答える