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)(public修飾子はまあまあ...)、すべての拡張メソッドを使用して実際のロギングを行います。

ここまでは良かった…それともあまり良くなかった?このアプローチに何か問題がありますか?そうでない場合、なぜ不便なのか:

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

1 に答える 1

3

それ自体は合理的なアプローチのように思えます1 - しかし、明示的に述べるという要件thisは、言語が拡張メソッドの周りでどのように機能するかの一部にすぎません。これにより、言語仕様の側面がより明確になると思われます。また、この要件は非常にまれであり (回避策も十分に簡単です)、5 文字を避けるためだけに物事を複雑にするよりも、現在のソリューションを使用する方がよいと感じられました。比較的まれなシナリオ。

単純な名前のメンバー ルックアップ (C# 4 仕様のセクション 7.6.2) は、悪化することなく十分に複雑です。単純な名前は、メソッドだけでなく、型または型パラメーターを参照できることを忘れないでください。すでに多くのことが起こっています。

仕事に着手したら、セクション7.6.5.2(拡張メソッドの呼び出し)の周りに、これに関する「内部情報」を提供する注釈があるかどうかを確認します。


1振り返ってみると、ログを実行しているエンティティが他のことログに記録したいというのは少し奇妙に思えます。私が期待する例外の唯一の種類は、ログが失敗したときであり、その場合、例外をログに記録するとも失敗します。

于 2012-05-22T06:09:44.383 に答える