C# MemberwiseClone() 方法在做什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2289420/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-07 01:06:38  来源:igfitidea点击:

What is the method MemberwiseClone() doing?

c#design-patternsprototypeclone

提问by Syed Tayyab Ali

I am confused with this code below,

我对下面的这段代码感到困惑,

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

Clone method of Developer class just creating a Employee clone, then how developer get another clone of developer.

Developer 类的 Clone 方法只是创建了一个 Employee 克隆,然后 developer 如何获得另一个 developer 克隆。

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

*/

采纳答案by Bozho

Because the method MemberwiseClone()is doing this for you. See the documentation

因为该方法MemberwiseClone()正在为您执行此操作。查看文档

The MemberwiseClone method creates a shallow copy by creating a new object, and then copying the nonstatic fields of the current object to the new object. If a field is a value type, a bit-by-bit copy of the field is performed. If a field is a reference type, the reference is copied but the referred object is not; therefore, the original object and its clone refer to the same object.

MemberwiseClone 方法通过创建一个新对象,然后将当前对象的非静态字段复制到新对象来创建浅拷贝。如果字段是值类型,则执行该字段的逐位复制。如果字段是引用类型,则复制引用但不复制引用的对象;因此,原始对象和它的克隆引用同一个对象。

Whenever you see a method you don't unerstand, you can trace who has declared it (in Visual Studio, I guess), and in turn see its documentation. That makes things pretty obvious most of the time.

每当你看到一个你不理解的方法时,你可以追踪谁声明了它(我猜是在 Visual Studio 中),然后查看它的文档。大多数时候,这让事情变得非常明显。

回答by supercat

The function MemberwiseClonecreates a new objects whose fields are bit-for-bit copies of those in the original structure. It is a necessary part of any inheritable class which allows cloning without use of Reflection or serialization, but it is only a small piece of the overall puzzle.

该函数MemberwiseClone创建一个新对象,其字段是原始结构中字段的逐位副本。它是任何允许在不使用反射或序列化的情况下进行克隆的可继承类的必要部分,但它只是整个难题的一小部分。

If you wish to allow cloning within an inheritable class, you should define a protected virtual T BaseClone<T>()cloning method; the base-level class which descends from Objectshould call base.MemberwiseClone; all other classes should use base.BaseClone<T>to get the new instance and then replace any mutable cloneable fields with clones of the ones in the original object.

如果你希望允许在一个可继承的类中进行克隆,你应该定义一个protected virtual T BaseClone<T>()克隆方法;派生自的基础类Object应调用base.MemberwiseClone; 所有其他类都应该base.BaseClone<T>用来获取新实例,然后用原始对象中的字段的克隆替换任何可变的可克隆字段。

I would also recommend defining the following interfaces:

我还建议定义以下接口:

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

That will allow for situations in which a class may have some descendants which can be cloned and some which cannot. Those which can be cloned can expose public cloning methods (which should chain to BaseClone<theirOwnType>). Methods which need cloneable derivatives of the base type can use parameters of type ICloneable<theBaseType>; this will allow them to accept any cloneable derivative of the base type, even if not all such derivatives share a common base class.

这将允许一个类可能有一些可以克隆的后代和一些不能克隆的情况。那些可以克隆的可以公开公共克隆方法(应该链接到BaseClone<theirOwnType>)。需要基类型的可克隆派生的方法可以使用类型的参数ICloneable<theBaseType>;这将允许它们接受基类型的任何可克隆派生类,即使并非所有此类派生类都共享一个公共基类。