假设我有一个界面,如下所示:
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)
实现为我喜欢的任何东西(公共修饰符都是meh ......)并使用所有扩展方法来进行实际记录。
到目前为止这么好......还是不太好?这种方法有问题吗?如果没有,那么为什么不方便:
catch (Exception ex) {
this.Log(ex); // this works
Log(ex); // this goes not
答案 0 :(得分:3)
对我来说这似乎是一种合理的方法 1 - 但明确陈述this
的要求只是语言如何围绕扩展方法工作的一部分。我怀疑这使得语言规范的各个方面更加清晰,并且这个要求非常罕见(并且解决方法非常容易),以至于认为使用当前解决方案比使事情变得更复杂只是为了避免五个字符更好相对罕见的情况。
简单名称的成员查找(C#4规范的第7.6.2节)足够复杂而不会使其变得更糟。不要忘记简单名称可以引用类型或类型参数,以及方法。那里已经发生了很多事情。
当我开始工作时,我将检查是否有任何关于7.6.5.2(扩展方法调用)的注释,它给出了“内部信息”。
1 在反思中,对于执行日志记录的实体也想要记录其他事情似乎有点奇怪 - 这是我期望的唯一一种异常要查看日志记录失败的时间,在这种情况下记录异常也会失败。