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

时间:2016-10-26 03:28:09

标签: c# override virtual

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

public abstract class AppenderSkeleton : IBulkAppender, 
    IAppender, IOptionHandler

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

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

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

我还没有尝试过运行它,但想知道现在是否有人可能会最终使用此实现进行运行?

谢谢, 尼克

2 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:0)

如果某人未将其方法标记为虚拟,则无法覆盖此方法。唯一的选择是实现自己的IAppender 另请注意,您不会覆盖接口方法,而是实现它们。

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

  

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

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

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

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