【问题标题】:What are the dangers of making a method virtual?使方法虚拟化有什么危险?
【发布时间】:2008-09-26 01:29:39
【问题描述】:

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

我无法预见将这些方法设为虚拟会有任何问题,但我想知道将方法设为虚拟有哪些潜在危险需要注意?

【问题讨论】:

  • 我从来没有用过Rhino,所以我很好奇它为什么需要这个。有人愿意解释吗?
  • 我假设 Rhino 重写了这些方法,以便通过使用相同类型但模拟行为来模拟接口。

标签: c# unit-testing mocking virtual-functions


【解决方案1】:

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

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 方法在其自己的构造函数的单行运行之前被调用。

【讨论】:

    【解决方案2】:
    • 如果您的用户覆盖了您的虚拟方法,您将无法在不破坏代码的情况下再次密封他们。
    • 您从构造函数调用的任何虚方法都可能归结为派生实现,如果它们不调用基方法而构造函数依赖于它,则对象可能处于无效状态

    【讨论】:

      【解决方案3】:

      Ayende 对虚拟方法的工作原理做了很好的处理:

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

      【讨论】:

        猜你喜欢
        • 2012-08-30
        • 2012-01-13
        • 1970-01-01
        • 2012-02-10
        • 1970-01-01
        • 2011-07-17
        • 2013-06-07
        • 2015-03-08
        相关资源
        最近更新 更多