一种避免构造函数中的虚拟调用的方法

时间:2010-10-30 14:40:27

标签: c# oop

考虑以下示例中的代码:

abstract class Car
{
    public abstract Engine CarEngine { get; protected set; }

    public Car()
    {
        CarEngine.EngineOverheating += new EventHandler(CarEngine_EngineOverheating);
    }

    void CarEngine_EngineOverheating(object sender, EventArgs e)
    {
        // Subscribing to the event of all engines
    }
}

sealed class Toyota : Car
{
    public Toyota()
    {
        this.CarEngine = new ToyotaEngine();
    }


    public override Engine CarEngine { get; protected set; }
}

abstract class Engine
{
    public event EventHandler EngineOverheating;
}

class ToyotaEngine : Engine
{

}

由于CarEngine尚未初始化,因此预期此代码不起作用。我有什么方法可以解决这种情况?

我看到他们的缺点有几个选项:

  1. 手动订阅每个子类 - 结果包含大量的样板代码,因此容易出错。
  2. Initialize()函数 - 容易出错且冗余。
  3. 我很高兴看到更多的想法。

    谢谢!

4 个答案:

答案 0 :(得分:7)

在Car中创建一个构造函数,将引擎作为参数并在订阅事件之前分配它,如下所示:

abstract class Car
{
    public abstract Engine CarEngine { get; protected set; }

    public Car(Engine carEngine)
    {
        CarEngine = carEngine;
        CarEngine.EngineOverheating += new EventHandler(CarEngine_EngineOverheating);
    }

    void CarEngine_EngineOverheating(object sender, EventArgs e)
    {
        // Subscribing to the event of all engines 
    }
}

sealed class Toyota : Car
{
    public Toyota()
        : base(new ToyotaEngine())
    {
    }


    public override Engine CarEngine { get; protected set; }
}

答案 1 :(得分:3)

你不能将Engine对象传递给Car的ctor,然后设置属性(可能会使setter变为私有)并注册事件处理程序吗?

答案 2 :(得分:0)

您可以尝试以下示例。这会在第一次访问时设置引擎。

sealed class Toyota : Car
{
    public Toyota()
    {
    }

    public override Engine CarEngine
    {
        get
        {
            var engine = base.CarEngine;

            if (engine == null)
            {
                engine = new ToyotaEngine();

                base.CarEngine = engine;
            }

            return engine;
        }
    }
}

答案 3 :(得分:0)

为什么不将引擎绑定到Car,然后在引擎实例化期间注册EventHandler(如果你需要一个具有这种设计的EventHandler,那就是)

实例化可能看起来像这样

new ToyotaEngine(myToyotaCarInstance).

我认为电机能够引用汽车是完全有效的。