2012-05-22 39 views
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)です(一般的な修飾子はmehのようなものです...)。実際のロギングを行うには、すべての拡張メソッドを使います。

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

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

このような状況では、もっと読みやすいと思われる 'Log(this、ex)'も呼び出すことができます。 –

+0

@HenkHolterman:Logger.Log(this、ex)を呼び出す必要があります。 –

答えて

3

それは自体に私には合理的なアプローチのように思える - しかし、明示的にthisを述べる要件は、言語が拡張メソッドの周りにどのように動作するかのほんの一部です。これは言語仕様の側面をより明確にしていると思われます。この要件は、現在のソリューションでは5文字を避けるために複雑にするよりも優れていると感じられていました。比較的まれなシナリオです。

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

私が作業を開始したら、7.6.5.2項(拡張メソッド呼び出し)の周辺に注釈があるかどうかチェックします。反射に


、それは他のものを記録したいもへのロギングを行うエンティティに少し奇妙に思えるん - とき、私はそれを見ることを期待したい例外の唯一の種類は次のようになりますロギングが失敗した場合、例外のロギングも失敗します。

+0

CoreServiceはほとんどがネットワーク経由でデータを取得し、データベースに格納しています。それは、その活動を記録するための手段が必要です。操作の一部が失敗した場合は、その操作を記録します。ロギングが失敗した場合、それを無視して(ネットワークロギングの場合)、またはシャットダウン自体(ファイルロギングの場合)、または何でも、それはインターフェイスの実装時に実装されます。 –

+0

@EugeneRyabtsev:ロギングインターフェイス自体を実装するのではなく、ロギングの仕方を知っているロギングメンバーを*持っている必要があります。これは実装の詳細です。他の人が使用できる機能として宣伝するべきものではなく、それがどのインタフェース用であるかです。ロギングの懸案事項を「ネットワーク経由でデータを取得する」から分離する。 * sole *ジョブがロギングしているクラスを作成し、そのクラスのインスタンスをCoreServiceで使用できるようにします。 –

+0

それから、logger.Log(...)として呼び出すことができるそのメンバーは、すべてのLog(...)コードを再利用するために多態性クラスでなければならず、私は何をログに記録したいのか、どのようにオン/オフをフィルタリングするか(最初にかなり大きく一般的にする)。もちろん、可能です。これまではC++で多重継承として実装していたので、クラスがそのアクティビティを実装してログに記録することができ、自己完結型であると思ったインターフェイスは近いと思います。 –