【问题标题】:Will memberwiseclone also copy members defined in derived class?memberwiseclone 还会复制派生类中定义的成员吗?
【发布时间】:2024-01-08 12:36:01
【问题描述】:

我需要定义一个进行浅拷贝的 Clone() 方法。 (无需深拷贝)

但我也需要它来复制派生类的成员。

如果我有

class Base {
     int baseMember;
     public (virtual?) Base Clone() {
         return (Base)this.MemberwiseClone()
     }
}

那么我应该为 Clone() 派生所有其他类吗? Base.Clone() 也会复制derivedMember 吗?

class Derived {
    int derivedMember;  //will this also be copied by base.Clone()?

    //Necessary?
    public new Derived (override Base?) Clone() {
        return (Derived)this.MemberwiseClone();
    }
}

【问题讨论】:

  • MemberwiseClone() 无论你从哪个函数调用它都是同一个函数。
  • 好吧,因为Clone 返回Base 它不会包含来自Derived 的任何内容,可能更好地实现IClonable 并从您的克隆方法返回object

标签: c# copy clone


【解决方案1】:

在基类上调用this.MemberwiseClone() 时,派生(非静态)字段是否也会被复制?

是的,你可以通过编写一个像这样的小测试来向自己保证:

private static void Main(string[] args)
{
    Student a = new Student() { Name = "John Doe", Id = 1 };
    Student b = (Student)a.Clone();
}

public class Person
{
    public string Name { get; set; }

    public virtual Person Clone()
    {
        return (Person)this.MemberwiseClone();
    }
}

public class Student:Person
{
    public int Id { get; set; }
}

另外这个问题已经answered here了。

我需要重写(或重写)派生类中的Clone 方法吗?

从技术上讲,这不是必需的,但正如您所见,您必须转换结果,因为base.Clone() 方法的返回类型是Person

或者,您可以像这样重写基类 Clone() 方法:

public T Clone<T>() where T:Person
{
    return (T)this.MemberwiseClone();
}

那你需要调用

Student b = a.Clone<Student>();

在您的派生类上。所以你只需要在基类中编写一次克隆方法。虽然我不确定这是否是最好的解决方案。

【讨论】:

  • 解释这个答案,另一个减少在方法上传递泛型需要的选择是更新基类以提供您的子类。 public class Person&lt;T&gt; { ... }public class Student : Person&lt;Student&gt; { ... }。然后子类可以调用.Clone()