5

假设我有一个界面,如下所示:

public interface ILoggable
{
    void Log(Func<string> message, Logger.Type type);
}

还有一些扩展方法,像这样:

public static class Logger
{
    public static void Log(this ILoggable loggable, Func<string> message) { loggable.Log(message, Type.Information); }
    public static void Log(this ILoggable loggable, string prefix, byte[] data, int len) { /* snip */ }
    public static void Log(this ILoggable loggable, Exception ex) { /* snip */ }
    // And so on...
}

然后在任何class CoreService : ServiceBase, ILoggable或这样的情况下,我将它实现public void Log(Func<string> message, Logger.Type type)为我喜欢的任何东西(公共修饰符有点……)并使用所有扩展方法来进行实际的日志记录。

到目前为止这么好……还是不太好?这种方法有问题吗?如果没有,那么为什么会带来不便:

catch (Exception ex) {
    this.Log(ex); // this works
    Log(ex); // this goes not
4

1 回答 1

3

这对我来说似乎是一种合理的方法1 - 但明确声明的要求this只是语言如何围绕扩展方法工作的一部分。我怀疑这会使语言规范的各个方面变得更清晰,而且这个要求非常罕见(而且解决方法也足够简单),人们认为使用当前的解决方案比仅仅为了避免在一个比较少见的场景。

简单名称的成员查找(C# 4 规范的第 7.6.2 节)已经足够复杂,而且不会变得更糟。不要忘记简单名称可以引用类型或类型参数,以及方法。那里已经发生了很多事情。

当我开始工作时,我会检查第 7.6.5.2 节(扩展方法调用)周围是否有任何注释,这些注释提供了关于此的“内部信息”。


1回想起来,进行日志记录的实体还想记录其他事情似乎有点奇怪- 我希望它看到的唯一一种异常是当日志记录失败时,在这种情况下记录异常会也失败了。

于 2012-05-22T06:09:44.383 回答