Поиск…


Синтаксис

  • объект ICloneable.Clone () {return Clone (); } // Частная реализация метода интерфейса, который использует нашу пользовательскую функцию public Clone ().
  • public Foo Clone () {return new Foo (this); } // Метод public clone должен использовать логику конструктора копирования.

замечания

Для CLR требуется object Clone() определения метода object Clone() который не является безопасным по типу. Общепринятой практикой является переопределение этого поведения и определение безопасного метода типа, который возвращает копию содержащего класса.

Автор должен решить, означает ли клонирование только мелкую копию или глубокую копию. Для неизменяемых структур, содержащих ссылки, рекомендуется сделать глубокую копию. Для классов, являющихся самими ссылками, вероятно, хорошо реализовать мелкую копию.

ПРИМЕЧАНИЕ. В C# метод интерфейса может быть реализован в частном порядке с приведенным выше синтаксисом.

Реализация ICloneable в классе

Внедрить ICloneable в класс с твист. Выполните открытый 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 для структуры, как правило, не требуется, потому что structs делает копию по порядку с оператором присваивания = . Но для дизайна может потребоваться реализация другого интерфейса, который наследуется от 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