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);
}


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow