【问题标题】:force explicit interface implementation强制显式接口实现
【发布时间】:2015-10-23 06:25:18
【问题描述】:

假设我们有一个接口IFoo

interface IFoo {
    void DoSomething();
}

现在我们有一个实现类,它在其构造函数中调用此方法:

class MyBase : IFoo {

    MyBase() { this.DoSomething(); }

    void DoSomething() { /* ... */ }
}

最后我们有了一个继承MyBase的类,但是shell提供了另一个接口IFoo的实现。但是在调试时,我意识到构造函数只能访问我理解的MyBase 上的实现。获得正确的接口实现我可以使用((IFoo) this).DoSomething();从构造函数中显式调用接口方法

class MyDerived : MyBase, IFoo {
    void DoSomething() { /* ... */ }
}

但是我如何才能强制该方法在使用它之前必须强制转换为该接口?我知道我可以在两个类中显式地实现接口,但是谁强迫我这样做呢?所以我们最终得出了这样的结论:我怎样才能强制继承我的类的人也显式地实现我的接口?

编辑:另一种方法是在MyBase 中使DoSomething 成为虚拟并省略派生类实现IFoo。但是,我在构造函数中调用虚拟成员时得到 R#-Warning。

【问题讨论】:

  • 能否请您也显示子类的代码? MyBase 需要具体化还是抽象化?
  • 你不能把方法变成虚拟的吗?
  • 具体来说。从基类的构造函数调用virtual 方法本身并没有错。当您覆盖该方法时,问题就来了。被覆盖的方法是在尚未调用其构造函数的类型中定义的,因此调用该方法可能不安全,这就是 ReSharper 警告您的内容。同样的问题也适用于通过接口显式调用显式实现的方法,只是 ReSharper 没有检测到这种情况。
  • 不,它不会,但这并不意味着它是安全的。如果您编写了一个在后代类型的构造函数执行之前可以安全调用的虚方法,那么通过接口调用显式实现的方法也是安全的。如果你写的虚方法调用它还不安全,那么通过接口调用这样的方法也不安全。
  • 您应该记录该方法将从基本构造函数调用,以表明它必须静默失败或成功运行,即使后代类型的构造函数尚未执行。

标签: c# inheritance interface


【解决方案1】:

这就是我要做的,将基类中的方法标记为虚拟,以便可以在子类中覆盖它。子类不需要显式实现接口,因为它继承了父类的行为。

interface IFoo {
    void DoSomething();
}

class MyBase : IFoo {

    MyBase() { this.DoSomething(); }

    **virtual** void DoSomething() { /* ... */ }
}

class MyDerived : MyBase {
    **override** void DoSomething() { /* ... */ }
}

【讨论】:

  • 我也想过这个,看我的编辑。然而,R# 打印了一个警告。也许我可以在我的场景中忽略它。
  • @HimBromBeere 请原谅我的无知,但 R# 是什么?
  • R# 警告很有用,但 R# 不是编译器。此代码是安全的并且以正确的方式编码。您正在更改子类中方法的行为,这是 OOP 的一部分。你知道 MyDerived 类的隐式构造函数会调用 MyBase 的构造函数(一个 base() 方法调用是隐式的作为 MyDerived 类的构造函数的第一行),就是这样。
  • @FranciscoGoldenstein 感谢您指出 OOP 的要点。
  • Resharper 警告是有原因的。在构造函数中调用虚方法通常是不安全的。在其他继承的类可以初始化它之前调用一个已初始化的参数(或通过其中一个子构造函数注入)是可能的。这是一个糟糕的设计,也是它显示为警告的原因之一。即使你知道你的实现没有这样做,如果有人继承了那个类,他仍然可能违反它,所以这段代码是安全的,正确的方式的说法是完全错误的
猜你喜欢
  • 2015-05-08
  • 2013-02-19
  • 2021-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-30
  • 2016-09-15
相关资源
最近更新 更多