将方法虚拟化的危险是什么?

时间:2020-03-06 14:45:38  来源:igfitidea点击:

我一直在用RhinoMocks进行模拟,它要求模拟的方法必须是虚拟的。很好,除了我们有一个自定义框架外,该框架包含我要模拟的方法,这些方法当前未标记为虚拟方法。

我无法预知将这些方法虚拟化的任何问题,但我想知道应该注意的将虚拟方法虚拟化的潜在危险是什么?

解决方案

  • 如果我们有覆盖虚拟方法的用户,则无法在不破坏代码的情况下再次密封它们。
  • 我们从构造函数调用的任何虚拟方法都可能落入派生的实现,并且如果它们不调用基础方法并且构造函数依赖于该方法,则该对象可能处于无效状态

Ayende对虚拟方法的工作方式有很好的处理:

http://ayende.com/Blog/archive/2007/01/05/HowVirtualMethodsWork.aspx

实际上,如果该方法未设计为被覆盖并且有人覆盖它,则可能会非常成问题。特别是,永远不要从构造函数中调用虚拟方法。考虑:

class Base {
    public Base() {
       InitializeComponent();
    }
    protected virtual void InitializeComponent() {
        ...
    }
}

class Derived : Base {
    private Button button1;
    public Derived() : base() {
        button1 = new Button();
    }
    protected override void InitializeComponent() {
        button1.Text = "I'm gonna throw a null reference exception"
    }
}

Derived类可能不知道虚拟方法调用将导致其InitializeComponent方法在其自己的构造函数的一行运行之前被调用。