Create an instance of derived class from the base class

爷,独闯天下 提交于 2019-12-01 04:12:31

问题


I have my abstract base class 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); //<-- ??
    }
}

Which is extended by my class B:

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

    //...
}

Since A is abstract, it cannot be instantiated, but the derived class can. Is it possible to, from class A, create a new instance of class B?

Suppose class A has many derived classes, how will it know which one to instantiate?

Well, I want to instantiate the same class (or type) my currently A is.

That is, if I'm calling the Clone method from a class B, I want to instantiate a new B. If I'm calling the Clone method from a class C, I want to instantiate a new C.

My approach was to write something like:

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

But that doesn't seem to work nor compile.

Is it possible to accomplish this in C#?

If it isn't, is there an explanation so I can understand?


回答1:


While I like Jamiec solution, I'm missing dirty solution using reflection :)

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:


Yes, this is possible with an abstract factory method on your base class

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);     
   }
}



回答3:


This can be done and your current approach is a well defined design pattern, though most implementations make the Clone an abstract virtual method and override it in all subclasses.

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( );
    }
}

Since you are using C# you could make use of the Activator class. You can make the Clone method virtual (not === abstract) with a default implementation of.

public abstract class A
{
    public virtual A Clone( )
    {
        // assuming your derived class contain a default constructor.
        return (A)Activator.CreateInstance(this.GetType( ));
    }
}

Edit - If you do not have a default parameter-less constructor in all of your derived classes, you can add parameters to the Activator.CreateInstance method

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

For varying constructors on the derived types I would recommend you override the Clone method specifically for those types instead of using the default implementation of Clone.



来源:https://stackoverflow.com/questions/25163478/create-an-instance-of-derived-class-from-the-base-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!