2010-02-18 4 views
28

Я путать с этим ниже код,Что такое метод MemberwiseClone()?

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

метод 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 

*/ 

ответ

45

Потому что метод MemberwiseClone() делает это за вас. См the documentation

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

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

+0

Обычно это все, что нужно клонировать. Примитивные поля - изолированные копии - определенно клонированные. Изменение примитивного поля элемента MemberwiseClone не будет замечено в исходном объекте. Поля ссылок на объекты одинаковы. Указание на другой объект не повлияет на другое. Тем не менее, сразу после ссылки объектов объекта MemberwiseCloning указывает на тот же объект. Клонирование происходит только на уровне прямого объекта, это не рекурсивный процесс. По моему опыту, нередко вам нужен рекурсивный глубокий клон, поэтому я обычно не затрудняюсь создать функцию Deep Clone. – Todd

11

Функция 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>; это позволит им принять любую клонируемую производную базового типа, даже если не все такие производные имеют общий базовый класс.

Смежные вопросы