重写未标记为虚的接口方法

本文关键字:接口 方法 记为 重写 | 更新日期: 2023-09-27 18:14:51

我正在写一个log4net appender。它们有一个AppenderSkeleton类来实现IAppender:

public abstract class AppenderSkeleton : IBulkAppender, 
    IAppender, IOptionHandler

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

然后我让我的类从IAppender派生,并显式地实现了IAppender. doappend()方法。我很惊讶代码编译没有问题。下面是我的DoAppend()方法:

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

我还没有试过运行它,但想知道如果有人可能现在运行时将结束与这个实现做什么?

谢谢,尼克

重写未标记为虚的接口方法

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

我建议使用复合而不是继承。不要让你的类继承自AppenderSkeleton,让它包含一个AppenderSkeleton的实例,并在你选择的地方使用它的方法。

Visual Studio甚至有一个快速的"通过私有变量实现接口"选项,如果你声明一个私有变量来实现你的类也实现的接口之一。它为你的类快速生成一个代理模式,调用私有成员的相应方法。

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

然而,你甚至不需要重写这个方法。
根据文件DoAppend

在将实际日志记录委托给子类特定的Append方法之前执行阈值检查并调用过滤器。

你不需要重写DoAppend方法,因为它描述了通用算法。
这是一种模板方法。

您需要重写Append方法,它是抽象的:

protected override void Append(LogginEvent loggingEvent)
{
    // Your actions here
}
相关文章: