【问题标题】:Abstract class --> get a new instace of current derived class抽象类 --> 获取当前派生类的新实例
【发布时间】:2023-03-04 02:34:01
【问题描述】:

是否可以获得当前派生类的新实例,该实例正在调用基本抽象类的函数?例如:

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

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

对于这个问题有更简单的解决方案吗?

【问题讨论】:

  • 你为什么需要它? bar1 已经是 Bar1 的一个实例
  • 如果派生类具有公共无参数构造函数,return Activator.CreateInstance(GetType()); 将起作用。
  • 是的,请参阅 mjwills 的链接或MSDN
  • @Pedro 您应该将解决方案添加为自我回答,而不是在原始帖子中。

标签: c# abstract-class derived-class


【解决方案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, ...); 

【讨论】:

    【解决方案2】:

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

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

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

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

    【讨论】:

      猜你喜欢
      • 2011-01-11
      • 2017-04-28
      • 2015-03-23
      • 2014-10-13
      • 2014-04-17
      • 1970-01-01
      • 2018-09-12
      • 1970-01-01
      • 2021-07-24
      相关资源
      最近更新 更多