C# Language
ICloneable
サーチ…
構文
- オブジェクトICloneable.Clone(){return Clone(); } //カスタムパブリックClone()関数を使用するインターフェイスメソッドのプライベート実装。
- public Foo Clone(){新しいFooを返します。 } //パブリッククローンメソッドはコピーコンストラクタロジックを利用する必要があります。
備考
CLR
は型保護されていないメソッド定義object Clone()
が必要です。この振る舞いをオーバーライドし、包含クラスのコピーを返す型安全メソッドを定義するのが一般的な方法です。
クローン作成が浅いコピーか深いコピーかを決定するのは作者次第です。参照を含む不変構造の場合は、詳細コピーを行うことをお勧めします。クラスそのものが参照されている場合は、浅いコピーを実装しても問題ありません。
注: C#
、上記の構文でインターフェイスメソッドをプライベートに実装できます。
ICloneableをクラスに実装する
ICloneable
をクラスに実装してICloneable
。公開型の安全なClone()
を公開し、 object Clone()
プライベートに実装しobject Clone()
。
public class Person : ICloneable
{
// Contents of class
public string Name { get; set; }
public int Age { get; set; }
// Constructor
public Person(string name, int age)
{
this.Name=name;
this.Age=age;
}
// Copy Constructor
public Person(Person other)
{
this.Name=other.Name;
this.Age=other.Age;
}
#region ICloneable Members
// Type safe Clone
public Person Clone() { return new Person(this); }
// ICloneable implementation
object ICloneable.Clone()
{
return Clone();
}
#endregion
}
その後、次のように使用されます。
{
Person bob=new Person("Bob", 25);
Person bob_clone=bob.Clone();
Debug.Assert(bob_clone.Name==bob.Name);
bob.Age=56;
Debug.Assert(bob.Age!=bob.Age);
}
bob
の年齢を変更しても、 bob_clone
の年齢は変更されません。これは、(参照)変数を代入するのではなく、複製を使用するためです。
構造体にICloneableを実装する
構造体は代入演算子=
メンバーワイドコピーを行うので、構造体のICloneableの実装は一般的には必要ありません。しかし、 ICloneable
を継承する別のインターフェイスを実装する必要があるかもしれません。
別の理由は、構造体にもコピーが必要な参照型(または配列)が含まれている場合です。
// Structs are recommended to be immutable objects
[ImmutableObject(true)]
public struct Person : ICloneable
{
// Contents of class
public string Name { get; private set; }
public int Age { get; private set; }
// Constructor
public Person(string name, int age)
{
this.Name=name;
this.Age=age;
}
// Copy Constructor
public Person(Person other)
{
// The assignment operator copies all members
this=other;
}
#region ICloneable Members
// Type safe Clone
public Person Clone() { return new Person(this); }
// ICloneable implementation
object ICloneable.Clone()
{
return Clone();
}
#endregion
}
その後、次のように使用されます。
static void Main(string[] args)
{
Person bob=new Person("Bob", 25);
Person bob_clone=bob.Clone();
Debug.Assert(bob_clone.Name==bob.Name);
}
Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow