4

これが内部メモリ/プロセッサでどのように発生するかはよくわかりません。

positionBlockを持つという名前のクラスを作成しました。また、ブロックを保存するための があります。List<Block>

まず、そのリストにブロックを追加します。

blocks.Add(new Block());

次に、そのブロックを複製して、リスト内の位置が異なる 2 つの独立したブロックを作成します。

Block clonedBlock = blocks[0];
blocks.Add(clonedBlock);

しかし、新しく作成したブロックの位置を変更すると、最初のブロックの位置も変更されます。

なぜそれを行うのですか、それを防ぐ方法はありますか?

ところで、リストにはいくつか奇妙な動作があるように見えることに気付きました。たとえば、この場合:

List<Block> list01 = new List<Block>();
[... add some blocks to that list ...]
List<Block> list02 = list01; // also tried: List<Block> list02 = list01.ToList();
[... change item in list01 ...] --> also changes that item in list02

これにより、リストにはポインターのようなものしか含まれず、ブロックを「複製」しようとすると、ポインターのみがコピーされますが、ポインターが指している位置は同じままであると推測されました。同じ質問: それを防ぐ方法はありますか?

編集: 解決策: Object.MemberwiseClone()- メソッド

4

1 に答える 1

3

あなたの推測は本質的に正しいです。クラスは参照型なので、行 Block clonedBlock = blocks[0]; clonedBlock を blocks[0] と同じアドレスに設定しています。一方に加えられた変更は、他方にも反映されます。他のブロックをコピーしてその位置を変更したいという何らかの理由がない限り、Block の新しいインスタンスを作成してリストに追加することをお勧めします。

これを処理する 1 つの方法は、ディープ コピーを実装することです (これは用語だと思います - C++ で何かをしてから何年も経ちます)。Block の新しいインスタンスを作成し、値を元のインスタンスから新しいインスタンスにコピーします。

ICloneable の実装を検討するか、単に独自のコピー メソッドを作成することもできます (実際には、ICloneable を実装する場合でも、独自のコピー メソッドを記述していることになります。インターフェイスは、それを使用するクラスがCloneメソッドを実装することを保証するだけです。深いか浅いかは次第です。実装者)。

また、Object.MemberwiseCloneメソッドも見てください。 Object.MemberwiseCloneは浅いコピーを行いますが、例セクションに浅いコピーと深いコピーの両方を行う例があります。

于 2013-06-01T02:39:46.187 に答える