覆盖未标记为虚拟的接口方法

overriding an interface method not marked as virtual

我正在写一个 log4net appender。他们有一个 AppenderSkeleton class 实现了 IAppender:

public abstract class AppenderSkeleton : IBulkAppender, 
    IAppender, IOptionHandler

他们 AppenderSkeleton class 的工作方式是他们实现 IAppender 的 DoAppend() 方法并为你做一堆工作,比如调用过滤器链,然后调用一个名为 Append() 的抽象方法.虽然这是合理的,但我想在过滤器 运行 之前执行我的一些代码。我可以自己实现 IAppender 接口,但起初我想我会尝试在派生的 class 中覆盖 DoAppend(),做我的事情,然后调用 base.DoAppend()。正是在这一点上,我注意到 AppenderSkeleton 没有将 DoAppend() 标记为虚拟,因为我收到一个编译器错误,表明我无法覆盖该方法,因为它没有被标记为虚拟。

然后我让我的 class 从 IAppender 派生并明确实现了 IAppender.DoAppend() 方法。我很惊讶代码编译没有问题。下面是我的 DoAppend() 方法:

void IAppender.DoAppend(LoggingEvent evnt)
{
    .
    .
    .
    base.DoAppend(evnt);
}

我还没有尝试 运行,但想知道现在是否有人可能 运行time 最终会用这个实现做什么?

谢谢, 尼克

如果有人没有将他的方法标记为虚拟的,那么就没有办法覆盖它。唯一的选择是实现自己的 IAppender.
另外请注意,您不会覆盖接口方法,而是实现它们。

但是,您甚至不需要覆盖此方法。
根据文档,DoAppend

performs threshold checks and invokes filters before delegating actual logging to the subclasses specific Append method.

您不需要覆盖 DoAppend 方法,因为它描述了通用算法。
有点像 Template method

您需要覆盖抽象的 Append 方法:

protected override void Append(LogginEvent loggingEvent)
{
    // Your actions here
}

@Rob 的回答是正确的 - 调用哪种方法(基础或派生)取决于您如何调用它。这将使它成为相当脆弱的代码。

我推荐的是使用组合而不是继承。不要让你的 class 从 AppenderSkeleton 继承,让它包含 AppenderSkeleton 的实例并在你选择的地方使用它的方法。

Visual Studio 甚至有一个快速的 "Implement interface through private variable" 选项,如果您声明一个实现了您的 class 也实现的接口之一的私有变量。它会快速为您的 class 生成代理模式,调用私有成员的相应方法。