C# 如何在基类中创建对象的克隆?

C# 如何在基类中创建对象的克隆?,c#,inheritance,C#,Inheritance,我需要一个在基类中创建对象的空克隆的方法?例如: public class ChildClass : ParentClass { public ChildClass() { } } public class ParentClass { public SomeMethod() { // I want to create an instance of the ChildClass here } } 到目前为止,我们在父类中定义了一个抽象方法。而且,所有的子类

我需要一个在基类中创建对象的空克隆的方法?例如:

public class ChildClass : ParentClass
{
   public ChildClass()
   {
   }
}
public class ParentClass
{
  public SomeMethod()
  {
     // I want to create an instance of the ChildClass here
  }
}
到目前为止,我们在父类中定义了一个抽象方法。而且,所有的子类都实现了它们。但是,所有的实现都是相同的,只是不同的类型

public class ChildClass : ParentClass
{
   public ChildClass()
   {
   }
   public ParentClass CreateEmpty()
   {
      return new ChildClass();
   }
}
public class ParentClass
{
  public SomeMethod()
  {
     // I want to create an instance of the ChildClass here
     ParentClass empty = CreateEmpty();

  }
  public abstract ParentClass CreateEmpty();
}

有没有办法从父类执行此操作,这样我就不必为每个不同的子类实现相同的逻辑?请注意,可能有更多级别的继承(即ChildClass:ChildClass:ParentClass)。

如果使用反射对您来说不是问题,您可以使用Activator类:


//In parent class
public ParentClass CreateEmpty()
{
    return (ParentClass)Activator.CreateInstance(this.GetType());
}
这将返回所需类型的空对象。请注意,此方法不需要是虚拟的


另一方面,我认为您当前的方法非常好,没有几行代码那么糟糕。

如果使用反射对您来说不是问题,您可以使用Activator类:


//In parent class
public ParentClass CreateEmpty()
{
    return (ParentClass)Activator.CreateInstance(this.GetType());
}
这将返回所需类型的空对象。请注意,此方法不需要是虚拟的


另一方面,我认为您当前的方法非常好,很少有代码行不是那么糟糕。

这有点实验性。我不知道这是否会导致循环依赖。已经好几个月没碰C#了

public class ParentClass<T> where T : ParentClass<T>, new() { // fixed
    public ParentClass() {
        var x = new T(); // fixed, was T.new()
    }
}

public class ChildClass : ParentClass<ChildClass> {
    public ChildClass() { }
}
公共类ParentClass,其中T:ParentClass,new(){//已修复
公共父类(){
var x=new T();//已修复,为T.new()
}
}
公共类子类:父类{
公共子类(){}
}

否则,选择Ravadre的ReflectionCode。

这有点实验性。我不知道这是否会导致循环依赖。已经好几个月没碰C#了

public class ParentClass<T> where T : ParentClass<T>, new() { // fixed
    public ParentClass() {
        var x = new T(); // fixed, was T.new()
    }
}

public class ChildClass : ParentClass<ChildClass> {
    public ChildClass() { }
}
公共类ParentClass,其中T:ParentClass,new(){//已修复
公共父类(){
var x=new T();//已修复,为T.new()
}
}
公共类子类:父类{
公共子类(){}
}

否则,请使用Ravadre的ReflectionCode。

您可以对该对象进行深度克隆


编辑:刚刚注意到克隆旁边的“空”字(我认为这是一个矛盾修饰法)。不管怎样,把这个回答留着,希望它能帮助其他人找到这个问题,因为他们正在寻找一个常规的克隆。

你可以对这个对象进行深度克隆


编辑:刚刚注意到克隆旁边的“空”字(我认为这是一个矛盾修饰法)。不管怎样,把这个回答留着,希望它能帮助其他发现这个问题的人,因为他们正在寻找一个常规的克隆。

我使用以下模式

优点:

  • 此模式确保类的私有和公共端克隆的类型安全
  • 输出类总是正确的
  • 您永远不会忘记覆盖“克隆”方法。“MyDerivedClass”不会返回“MyDerivedClass”以外的其他类
缺点:

  • 对于一个类,您需要创建一个接口和两个类(prototype和final)
样本:

// Common interface for cloneable classes.
public interface IPrototype : ICloneable {
    new IPrototype Clone();
}

// Generic interface for cloneable classes.
// The 'TFinal' is finaly class (type) which should be cloned.
public interface IPrototype<TFinal> where TFinal : IPrototype<TFinal> {
    new TFinal Clone();
}

// Base class for cloneable classes.
// The 'TFinal' is finaly class (type) which should be cloned.
public abstract class PrototypeBase<TFinal> : IPrototype<TFinal> where TFinal : PrototypeBase<TFinal> {
    public TFinal Clone() {
        TFinal ret = this.CreateCloneInstance();
        if ( null == ret ) {
            throw new InvalidOperationException( "Clone instance was not created." );
        }

        this.FillCloneInstance( ret );
        return ret;
    }

    // If overriden, creates new cloned instance
    protected abstract TFinal CreateCloneInstance();

    // If overriden, fill clone instance with correct values.
    protected abstract void FillCloneInstance( TFinal clone );

    IPrototype IPrototype.Clone() { return this.Clone(); }
    object ICloneable.Clone() { return this.Clone(); }
}

// Common interface for standalone class.
public interface IMyStandaloneClass : IPrototype<IMyStandaloneClass> {
    string SomeText{get;set;}
    string SomeNumber{get;set;}
}

// The prototype class contains all functionality exception the clone instance creation.
public abstract class MyStandaloneClassPrototype<TFinal> : PrototypeBase<TFinal>, IMyStandaloneClass where TFinal : MyStandaloneClassPrototype<TFinal> {
    public string SomeText {get; set;}
    public int SomeNumber {get; set}

    protected override FillCloneInstance( TFinal clone ) {
        // Now fill clone with values
        clone.SomeText = this.SomeText;
        clone.SomeNumber = this.SomeNumber;
    }
}

// The sealed clas contains only functionality for clone instance creation.
public sealed class MyStandaloneClass : MyStandaloneClassPrototype<MyStandaloneClass> {
    protected override MyStandaloneClass  CreateCloneInstance() {
        return new MyStandaloneClass();
    }
}

public interface IMyExtendedStandaloneClass : IMyStandaloneClass, IPrototype<IMyExtendedStandaloneClass> {
    DateTime SomeTime {get; set;}
}

// The extended prototype of MyStandaloneClassPrototype<TFinal>.
public abstract class MyExtendedStandaloneClassPrototype<TFinal> : MyStandaloneClassPrototype<TFinal> where TFinal : MyExtendedStandaloneClassPrototype<TFinal> {
    public DateTime SomeTime {get; set;}

    protected override FillCloneInstance( TFinal clone ) {
        // at first, fill the base class members
        base.FillCloneInstance( clone );

        // Now fill clone with values
        clone.SomeTime = this.SomeTime;
    }
}

public sealed class MyExtendedStandaloneClass : MyExtendedStandaloneClassPrototype<TFinal> {
    protected override MyExtendedStandaloneClass CreateCloneInstance() {
        return new MyExtendedStandaloneClass 
    }
}
//可克隆类的公共接口。
公共接口IPrototype:可克隆{
新的IPrototype克隆();
}
//可克隆类的通用接口。
//“TFinal”最终是应克隆的类(类型)。
公共接口IPrototype,其中TFinal:IPrototype{
新的t最终克隆();
}
//可克隆类的基类。
//“TFinal”最终是应克隆的类(类型)。
公共抽象类PrototypeBase:IPrototype,其中TFinal:PrototypeBase{
公共TFinal克隆(){
TFinal ret=this.CreateCloneInstance();
if(null==ret){
抛出新的InvalidOperationException(“未创建克隆实例”);
}
这是一个很好的例子;
返回ret;
}
//如果重写,将创建新的克隆实例
受保护的抽象TFinal CreateCloneInstance();
//如果覆盖,请使用正确的值填充克隆实例。
受保护的抽象空填充克隆实例(t最终克隆);
IPrototype IPrototype.Clone(){返回this.Clone();}
对象ICLOnable.Clone(){返回此.Clone();}
}
//独立类的公共接口。
公共接口IMyStandaloneClass:IPrototype{
字符串SomeText{get;set;}
字符串SomeNumber{get;set;}
}
//prototype类包含克隆实例创建之外的所有功能。
公共抽象类MyStandaloneClassPrototype:PrototypeBase,IMyStandaloneClass,其中TFinal:MyStandaloneClassPrototype{
公共字符串SomeText{get;set;}
公共整数SomeNumber{get;set}
受保护的重写FillCloneInstance(t最终克隆){
//现在用值填充克隆
clone.SomeText=this.SomeText;
clone.SomeNumber=this.SomeNumber;
}
}
//密封的clas仅包含克隆实例创建功能。
公共密封类MyStandaloneClass:MyStandaloneClass原型{
受保护的覆盖MyStandaloneClass CreateCloneInstance(){
返回新的MyStandaloneClass();
}
}
公共接口IMYExtendedStatandLoneClass:IMYStandLoneClass,IPrototype{
日期时间{get;set;}
}
//MyStandaloneClassPrototype的扩展原型。
公共抽象类MyExtendedStandaloneClassPrototype:MyStandaloneClassPrototype其中TFinal:MyExtendedStandaloneClassPrototype{
公共日期时间{get;set;}
受保护的重写FillCloneInstance(t最终克隆){
//首先,填充基类成员
base.FillCloneInstance(克隆);
//现在用值填充克隆
clone.someone=this.someone;
}
}
公共密封类MyExtendedStandaloneClass:MyExtendedStandaloneClass原型{
受保护的重写MyExtendedStandaloneClass CreateCloneInstance(){
返回新的MyExtendedStandaloneClass
}
}

我正在使用以下模式

优点: