C# Language
Iloneable
Szukaj…
Składnia
- obiekt ICloneable.Clone () {return Clone (); } // Prywatna implementacja metody interfejsu, która korzysta z naszej niestandardowej publicznej funkcji Clone ().
- public Foo Clone () {zwróć nowe Foo (this); } // Metoda publicznego klonowania powinna wykorzystywać logikę konstruktora kopiowania.
Uwagi
CLR
wymaga object Clone()
definicji metody object Clone()
który nie jest bezpieczny dla typu. Powszechną praktyką jest przesłonięcie tego zachowania i zdefiniowanie bezpiecznej metody typu, która zwraca kopię zawierającej klasy.
Od autora zależy, czy klonowanie oznacza tylko płytką kopię, czy głęboką kopię. W przypadku niezmiennych struktur zawierających odniesienia zaleca się wykonanie głębokiej kopii. W przypadku klas, które same są odniesieniami, prawdopodobnie dobrze jest zaimplementować płytką kopię.
UWAGA: W języku C#
metoda interfejsu może być zaimplementowana prywatnie przy użyciu powyższej składni.
Implementowanie ICloneable w klasie
Zaimplementuj ICloneable
w klasie z niespodzianką. Odsłoń bezpieczny typ publiczny Clone()
i zaimplementuj object Clone()
prywatnie.
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
}
Później należy użyć w następujący sposób:
{
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);
}
Zauważ, że zmiana wieku bob
nie zmienia wieku bob_clone
. Wynika to z faktu, że projekt wykorzystuje klonowanie zamiast przypisywania zmiennych (referencyjnych).
Implementowanie ICloneable w strukturze
Implementacja ICloneable dla struktury nie jest na ogół potrzebna, ponieważ struktury wykonują kopię członka za pomocą operatora przypisania =
. Ale projekt może wymagać implementacji innego interfejsu, który dziedziczy po ICloneable
.
Innym powodem może być to, że struct zawiera typ odwołania (lub tablicę), który również wymaga skopiowania.
// 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
}
Później należy użyć w następujący sposób:
static void Main(string[] args)
{
Person bob=new Person("Bob", 25);
Person bob_clone=bob.Clone();
Debug.Assert(bob_clone.Name==bob.Name);
}