从基类创建派生类的实例

时间:2014-08-06 14:47:18

标签: c# oop inheritance abstract-class instantiation

我的抽象基类 A

public abstract class A : ICloneable {

    public int Min { get; protected set; }
    public int Max { get; protected set; }

    public A(int low, int high)
    {
        this.Min = low;
        this.Max = high;
    }

    //...

    public object Clone()
    {
        return new this(this.Min, this.Max); //<-- ??
    }
}

我的课程 B 扩展了

public class B : A
{
    public B(int low, int high) : base(low, high) { }

    //...
}

由于 A 是抽象的,因此无法实例化,但派生类可以。 是否可以从 A 班级创建班级 B 的新实例?

假设类 A 有许多派生类,它将如何知道实例化哪一个?

好吧,我想实例化我当前 A 所在的同一个类(或类型)。

也就是说,如果我从类 B 调用Clone方法,我想实例化一个新的 B 。 如果我从 C 类调用Clone方法,我想要实例化一个新的 C

我的方法是写一些类似的东西:

return new this(this.Min, this.Max);

但这似乎不起作用也不能编译。

是否可以在 C#

中完成此操作

如果不是,是否有解释,我可以理解?

3 个答案:

答案 0 :(得分:6)

是的,这可以通过基类

上的抽象工厂方法实现
public abstract class A
{
   public int Min { get; protected set; }
   public int Max { get; protected set; }

   public A(int low, int high)
   {
       this.Min = low;
       this.Max = high;
   }
   protected abstract A CreateInstance(int low, int high);

   public object Clone()
   {
      return this.CreateInstance(this.Min,this.Max);
   }
}

public class B:A
{
   public B(int low, int high)
      : base(low,high)
   {
   }
   protected override A CreateInstance(int low, int high)
   {
      return new B(low,high);     
   }
}

答案 1 :(得分:4)

虽然我喜欢Jamiec解决方案,但我还是缺少使用反射的脏解决方案:)

public class A {
  public object Clone() {
    var type = GetType().GetConstructor(new[] { typeof(int), typeof(int) });
    return type.Invoke(new object[] { this.Min, this.Max });
  }
}

答案 2 :(得分:1)

这可以完成,您当前的方法是一个定义良好的设计模式,但大多数实现使Clone成为一个抽象的虚方法,并在所有子类中覆盖它。

public abstract class A
{
    public abstract A Clone( );
}

public class B : A
{
    public override A Clone( )
    {
        return new B( );
    }
}

public class C : A
{
    public override A Clone( )
    {
        return new C( );
    }
}

由于您使用的是C#,因此您可以使用Activator类。您可以使用。

的默认实现使Clone方法虚拟(不是=== abstract)
public abstract class A
{
    public virtual A Clone( )
    {
        // assuming your derived class contain a default constructor.
        return (A)Activator.CreateInstance(this.GetType( ));
    }
}

修改 如果在所有派生类中没有默认的无参数构造函数,则可以向Activator.CreateInstance方法添加参数

(A)Activator.CreateInstance(this.GetType( ), this.Min, this.Max);

对于派生类型的不同构造函数,我建议您专门为这些类型覆盖Clone方法,而不是使用Clone的默认实现。