Подтвердить что ты не робот

Что делает метод MemberwiseClone()?

Я смущен этим кодом ниже,

Developer devCopy = (Developer)dev.Clone();

Метод клонирования класса Developer, просто создающий клон Employee, а затем как разработчик получает еще один клон разработчика.

public abstract class Employee
{
    public abstract Employee Clone();

    public string Name { get; set; }
    public string Role { get; set; }
}


public class Typist : Employee
{
    public int WordsPerMinute { get; set; }

    public override Employee Clone()
    {
        return (Employee)MemberwiseClone();
    }

    public override string ToString()
    {
        return string.Format("{0} - {1} - {2}wpm", Name, Role, WordsPerMinute);
    }
}


public class Developer : Employee
{
    public string PreferredLanguage { get; set; }

    public override Employee Clone()
    {
        return (Employee)MemberwiseClone();
    }

    public override string ToString()
    {
        return string.Format("{0} - {1} - {2}", Name, Role, PreferredLanguage);
    }
}


Developer dev = new Developer();
dev.Name = "Bob";
dev.Role = "Team Leader";
dev.PreferredLanguage = "C#";

Developer devCopy = (Developer)dev.Clone();
devCopy.Name = "Sue";

Console.WriteLine(dev);
Console.WriteLine(devCopy);

/* OUTPUT

Bob - Team Leader - C#
Sue - Team Leader - C#

*/

Typist typist = new Typist();
typist.Name = "Kay";
typist.Role = "Typist";
typist.WordsPerMinute = 120;

Typist typistCopy = (Typist)typist.Clone();
typistCopy.Name = "Tim";
typistCopy.WordsPerMinute = 115;

Console.WriteLine(typist);
Console.WriteLine(typistCopy);

/* OUTPUT

Kay - Typist - 120wpm
Tim - Typist - 115wpm

*/
4b9b3361

Ответ 1

Потому что метод MemberwiseClone() делает это для вас. См. документацию

Метод MemberwiseClone создает мелкую копию, создавая новый объект, а затем копирует нестатические поля текущего объекта в новый объект. Если поле является типом значения, выполняется побитовая копия поля. Если поле является ссылочным типом, ссылка копируется, но упомянутый объект не является; поэтому исходный объект и его клон относятся к одному и тому же объекту.

Всякий раз, когда вы видите метод, который вы не понимаете, вы можете проследить, кто его объявил (в Visual Studio, я думаю), и, в свою очередь, посмотреть его документацию. Это делает вещи довольно очевидными большую часть времени.

Ответ 2

Функция MemberwiseClone создает новые объекты, поля которых являются битовыми копиями тех, что находятся в исходной структуре. Это неотъемлемая часть любого наследуемого класса, который позволяет клонировать без использования Reflection или сериализации, но это всего лишь небольшая часть общей головоломки.

Если вы хотите разрешить клонирование внутри наследуемого класса, вы должны определить метод клонирования protected virtual T BaseClone<T>(); класс базового уровня, который опускается от Object, должен вызывать base.MemberwiseClone; все остальные классы должны использовать base.BaseClone<T>, чтобы получить новый экземпляр, а затем заменить любые изменяемые клонируемые поля клонами тех, что находятся в исходном объекте.

Я также рекомендовал бы определить следующие интерфейсы:

interface ISelf<out T> {T Self();}
interface ICloneable<out T> : ISelf<T> {T Clone();}

Это позволит использовать ситуации, в которых класс может иметь некоторые потомки, которые могут быть клонированы, а некоторые из них не могут. Те, которые могут быть клонированы, могут раскрывать общедоступные методы клонирования (которые должны быть привязаны к BaseClone<theirOwnType>). Методы, которые нуждаются в клонируемых производных базового типа, могут использовать параметры типа ICloneable<theBaseType>; это позволит им принять любую клонируемую производную базового типа, даже если не все такие производные имеют общий базовый класс.