[英]Create an instance of derived class from the base class
I have my abstract base class A : 我有我的抽象基类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 : 我的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. 由于A是抽象的,因此无法实例化,但派生类可以。 Is it possible to, from class A , create a new instance of class B ? 是否可以从A类创建B类的新实例?
Suppose class A has many derived classes, how will it know which one to instantiate? 假设类A有许多派生类,它将如何知道实例化哪一个?
Well, I want to instantiate the same class (or type) my currently A is. 好吧,我想实例化我目前A的同一个类(或类型)。
That is, if I'm calling the Clone
method from a class B , I want to instantiate a new B . 也就是说,如果我从B类调用Clone
方法,我想实例化一个新的B. If I'm calling the Clone
method from a class C , I want to instantiate a new C . 如果我从C类调用Clone
方法,我想实例化一个新的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# ? 是否有可能在C#中实现这一目标?
If it isn't, is there an explanation so I can understand? 如果不是,是否有解释所以我能理解?
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);
}
}
While I like Jamiec solution, I'm missing dirty solution using reflection :) 虽然我喜欢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 });
}
}
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. 这可以完成,您当前的方法是一个定义良好的设计模式,但大多数实现使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( );
}
}
Since you are using C# you could make use of the Activator
class. 由于您使用的是C#,因此可以使用Activator
类。 You can make the Clone
method virtual (not === abstract) with a default implementation of. 您可以使用默认实现将Clone
方法设为虚拟(不是=== abstract)。
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 编辑 -如果在所有派生类中没有默认的无参数构造函数,则可以向Activator.CreateInstance
方法添加参数
(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
. 对于派生类型的不同构造函数,我建议您专门为这些类型重写Clone
方法,而不是使用Clone
的默认实现。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.