3

このメソッドを持つTileクラスがあります:

    public object Clone()
    {
        return MemberwiseClone();
    }

Checkerそして、から継承する別のクラスTile

であるBoardクラスもありList<Tile>ます。ボードのクローンを作成したいので、次のように記述しました。

    public Board Clone()
    {
        var b = new Board(width, height);
        foreach (var t in this) b.Add(t.Clone());
        return b;
    }

しかし、それはエラーをスローします:

'object'から'Checkers.Tile'に変換できません

これで、メソッドが代わりにTile.Clone返すようにすることができますが、サブの追加のプロパティもコピーしますか?TileMemberwiseCloneChecker


Board.Cloneそれが問題ではない場合、上記の方法とこれの意味上の違いは何ですか?

    public Board Clone()
    {
        using (var ms = new MemoryStream())
        {
            var bf = new BinaryFormatter();
            bf.Serialize(ms, this);
            ms.Position = 0;
            return (Board)bf.Deserialize(ms);
        }
    }

ボードを印刷しても同じように見えますが、プログラムに与える影響は間違いなく異なります。何かが複製されているとは思いませんが、参照が返されています。Boardctorは次のようになります。

    public Board(int width = 8, int height = 8)
    {
        this.width = width;
        this.height = height;
        this.rowWidth = width / 2;
        this.Capacity = rowWidth * height;
    }

このTileクラスには実際にはプロパティがありません。チェッカーには2つの列挙型プロパティがあります。

public enum Color { Black, White };
public enum Class { Man, King };

public class Checker : Tile
{
    public Color Color { get; set; }
    public Class Class { get; set; }
4

3 に答える 3

4

はい、MemberwiseCloneCheckerは-onlyフィールドもコピーします。MemberwiseCloneは、Cloneメソッドの戻り型を知ることができません。したがって、その動作はそれに依存することはできません。


クローンの実装とシリアル化の違いについて:タイルの浅いコピーMemberwiseCloneを作成します:タイル(またはチェッカー)がオブジェクトを参照している場合でも、タイルのクローンは(そのコピーではなく)同じオブジェクトを参照します。

一方、シリアル化コードは、ボードのディープコピーを作成するためのよく知られた方法です。依存オブジェクトのツリー全体がシリアル化および逆シリアル化されます。

もちろん、これは、タイル(またはチェッカー)に参照型のフィールドが含まれている場合にのみ違いがあります。

于 2010-09-05T21:59:17.317 に答える
2

私が見ているように、クローン作成に関して、オブジェクトには4つの主要なクラスがあります。

  1. 何かを壊さずにクローンを作成できないもの
  2. クローン作成可能性を公に約束していないが、MemberwiseCloneを使用して適切にクローンを作成できるもの
  3. クローン作成可能性を公に約束していないが、MemberwiseClone以外の方法でクローンを作成できるもの
  4. 自分自身と派生クラスに代わってクローン可能性を公に宣伝するもの。
残念ながら、タイプがMemberwiseCloneメソッドを覆い隠さない限り、一般的に#1と#2を区別する良い方法はありません。タイプ#3をセミクローン可能と呼ぶのが好きです。

セミクローン可能なオブジェクトは、Objectまたは基本クラスタイプのいずれかを返すCloneBaseのようなものと呼ばれる保護された仮想メソッドをサポートする必要があります(実際にはそれほど重要ではありません)。最下位レベルのCloneBaseメソッドは、MemberwiseCloneを呼び出し、複製されたオブジェクトを修正するために必要なことをすべて実行する必要があります。クローン作成をサポートする派生クラスには、CloneBaseを呼び出して結果をタイプキャストするだけのパブリックCloneメソッドが必要です。基本クラスレベルのクローン作成後に修正およびオブジェクト化するために必要な派生クラスロジックは、CloneBaseのオーバーライドに含める必要があります。

クローン作成をサポートしない派生クラスが必要な場合は、パブリックをセミクローン可能クラスにし、そのクラスからCloneableWhateverを継承します。これは、パブリックCloneメソッドを追加する以外は何もしません。このようにして、クローン不可能なクラスはセミクローン可能なクラスから派生でき、クローン可能なクラスはCloneableWhateverから派生できます。

于 2010-10-16T22:12:18.927 に答える
1

はい、そうなります-それはポリモーフィズムです。

于 2010-09-05T22:02:14.420 に答える