【问题标题】:Get instance of child class获取子类的实例
【发布时间】:2013-09-26 13:45:58
【问题描述】:

我有一个基本抽象类“BaseEngine”和一个子类“Engine : BaseEngine”。

引擎有一个名为“实例”的引擎类型的公共属性:

public Engine Instance
{ get; set; }

我想从 BaseEngine 获取这个实例。我已经试过了:

public abstract BaseEngine<T> where T : class
{
    public T Instance { get; set; }
}

public Engine : BaseEngine<Engine>

但它会创建递归。

你有什么建议吗? 谢谢!

更新

我有很多从 BaseEngine 类派生的类。每个子类都有实际上做同样事情的方法。我试图将这些方法移到基类中,以便在发生更改时更改更少的代码。我将尝试找到另一种方法来做到这一点,因为我所要求的无法完成。感谢您的回复。

【问题讨论】:

  • 您需要多解释一下您要做什么。您所描述的内容不能按原样完成,用其他术语想象它更容易看出,如果您有 ShapeSquare 您试图从 Shape 函数内部引用 Square。如果您告诉我们您要完成的工作we can help you solve that problem instead.
  • 你想做什么?这一切都很奇怪。
  • 父类不应该知道实现类型的细节,这很难闻。
  • 为什么你的基类需要知道派生类?基类应该对派生类一无所知,因为它通常表示代码异味。
  • “它创建递归”是什么意思?

标签: c# class inheritance


【解决方案1】:

由于我不太了解您要做什么,您应该知道,如果您有一个 Engine 的实例,那么 BaseEngine 中的代码仍然有一个 Engine,即使它没有不知道。无论如何,它不应该知道派生类是什么,因为那会是代码异味。

但是,如果您需要从基类访问 Engine 中的函数,您可以将基类创建为 abstract 并在基类中创建 abstract 函数(即没有实现的函数)并具有派生类实现它们。

或者您可以创建 virtual 函数并拥有派生类 override 它们,然后可以替换或添加其他功能。

这通常是在派生类中具有基类访问功能的推荐方式。

例如:

public abstract class BaseEngine
{
  public void DoStuff()
  {
    // Do some things here
    DoDerivedStuff();
    // Do some other things here
  }

  protected abstract void DoDerivedStuff();

  public virtual void DoOverridableStuff()
  {
    // Do stuff in here.
  }
}

public class Engine : BaseEngine
{
   protected override void DoDerivedStuff()
   {
     // Do stuff here that is particular to this derived type.
   }

   public override void DoOverridableStuff()
   {
      // Do additional stuff for the Engine class if necessary
      base.DoOverridableStuff(); // You can omit this if you don't 
                                 // want to do what the base is doing.
      // Do more stuff for the engine class if necessary
   }
}

【讨论】:

    【解决方案2】:

    您不能将Instance 属性键入到子类,您需要返回BaseEngine,但您可以在该属性中返回Engine 的实例,调用者只需在需要时将其转换是。

    public abstract class BaseEngine
    {
        public BaseEngine Instance {get; private set;}
    }
    
    public class FarrariEngine : BaseEngine
    {
        public FarrariEngine()
        {
            this.Instance = this; //This line is VERY weird to me.
        }
    }
    
    public class LawnmowerEngine : BaseEngine
    {
        public LawnmowerEngine ()
        {
            this.Instance = this;
        }
    }
    
    
    public class Program
    {
        public static Main(string[] args)
        {
            var farrari = new FarrariEngine();
            Engine currentEngine = farrari.Instance. //Works
            FarrariEngine currentFarrariEngine = (FarrariEngine)farrari.Instance. //Also works.
    
            var lawnMower = new LawnmowerEngine();
            Engine currentEngine = lawnMower.Instance. //Works
            LawnmowerEngine currentLawnmowerEngine = (LawnmowerEngine)lawnMower.Instance. //Also works.
        }
    }
    

    这在.NET框架中很常见,看WebRequest的子代。像GetResponse() 这样的东西都会返回the base type

    但是很奇怪,您有一个返回父类类型的属性(特别是称为Instance),该属性是否应该是静态的并且您正在尝试执行单例模式?

    【讨论】:

    • “这在 .NET 框架中很常见”这不是一个好的理由。大量 .NET 框架早于泛型,而且由于 C# 使用具体化而不是类型擦除,因此无法改造现有类以使用它们。该 API 的从头实现可以轻松使用 OP 的结构,而且它实际上非常有意义。
    • 实际上它甚至不是 OP 的构造。 interface Request&lt;TResponse&gt; where TResponse : Response { TResponse {get;} } 是非常好的非递归泛型使用。
    猜你喜欢
    • 2013-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-26
    • 2010-10-05
    • 2017-04-22
    相关资源
    最近更新 更多