抽象类 - >获得当前派生类的新实例

时间:2017-11-16 11:51:44

标签: c# abstract-class derived-class

是否有可能获得调用基本抽象类函数的当前派生类的新实例?例如:

class Bar1 : Foo
{

}
class Bar2 : Foo
{

}

abstract class Foo
{
    public Foo CreateAnotherInstance()
    {
        return new Bar1/Bar2();   // depending on the calling derived class
    }
}

应该导致:

Bar1 bar1 = new Bar1();
Bar2 bar2 = new Bar2();
Foo bar1_2 = bar1.CreateAnotherInstance();  // Should be a new Bar1 instance
Foo bar2_2 = bar1.CreateAnotherInstance();  // Should be a new Bar2 instance

我发现的唯一方法是创建实例是一个抽象方法,其中实例在每个派生类中创建,如:

class Bar1 : Foo
{
    public override Foo CreateAnotherInstance()
    {
        return new Bar1();
    }
}

class Bar2 : Foo
{
    public override Foo CreateAnotherInstance()
    {
        return new Bar2();
    }
}

abstract class Foo
{
    public abstract Foo CreateAnotherInstance();
}

但是这样,我必须为每个派生类创建方法。

是否有更简单的解决方案可以解决这个问题?

2 个答案:

答案 0 :(得分:1)

感谢RenéVogt和mjwills提供答案:

使用

(Foo)Activator.CreateInstance(GetType()); 

所以将抽象类更改为:

abstract class Foo
{
    public Foo CreateAnotherInstance()
    {
        return (Foo)Activator.CreateInstance(GetType());
    }
}

如果构造函数不是无参数的:

(Foo)Activator.CreateInstance(GetType(), para1, para2, ...); 

答案 1 :(得分:1)

虽然Activator.CreateInstance是一个很好的方法,但我不确定这是一个属于基本抽象类的方法,或者确实属于这些类中的任何一个。这不会破坏多态性吗?或者至少Liskov替代原则?

在任何情况下,作为替代方案,如何创建一个适用于任何类型的简单方法,而不仅仅是上面的方法。 e.g。

public static T CreateNew<T>(params object[] parms)
{
  return (T) Activator.CreateInstance(typeof(T), parms);
}

这也允许你传入构造函数参数(如果有的话)。