2010-02-11 31 views
4

好吧,在閱讀了danben對這個post的回答之後,我想我確信需要寫這種代碼,至少在很多情況下。我的經理似乎也同意。如何在c#中重構log4net語句?

if (log.IsDebugEnabled) 
    log.Debug("ZDRCreatorConfig("+rootelem.ToString()+")"); 
if (log.IsInfoEnabled) 
    log.Info("Reading Configuration . . ."); 

它的問題是它錯誤的挫折感了我看到所有這些if語句隨處放置只是做了簡單的日誌語句。

我的問題是,我們如何可以將這個重構成一個類,而不會重現必須評估日誌方法參數的性能問題?

只要把它在一個類的靜態方法沒有幫助,因爲當你傳遞對象的消息仍必須評估參數:

public class LogHelper { 
    public static Info(ILog log, Object message) { 
      if(log.IsInfoEnabled) { log.Info(message); } 
    } 
} 

C#顯然不支持強制的方法內聯,因此解決方案不可用。 MACRO在C#中不受支持。我們可以做什麼?!?!

更新: 感謝您的回覆,我沒有忘記這個;這在我的名單上現在只是很低的優先權。一旦我陷入困境,我會去解決問題並給予答案。謝謝。

另一個更新:
好吧......我還沒有看到這一點,而且你們都值得正確的答案;但我同意Tanzelax的答案,因爲我認爲他們會自動內聯。他發佈的鏈接說服了我很好的工作,我現在不應該太擔心這個,這也是很好的笑聲。我以後會繼續關注這些lambda的事情。謝謝您的幫助!

+1

您是否試過NLog? IMO NLog往往比Log4Net更清潔。 – 2010-02-11 22:34:25

回答

3

如果靜態輔助:

public static class LogHelper { 
    public static void Info(this ILog log, Func<Object> messageProvider) { 
     if(log.IsInfoEnabled) { log.Info(messageProvider()); } 
    } 
} 

與說它方法很簡單,它應該自動內聯,並且將具有匹配的性能。

At what level C# compiler or JIT optimize the application code?

+0

謝謝,我真的認爲可能是這樣。當我有機會並在稍後更新時,我會閱讀它。 – cchampion 2010-02-11 22:06:03

15

一個簡單的解決方案是使用lambda表達式來有效地推遲消息的生成,直到它的需要,如果它的需要

log.Info(() => "This is expensive: " + CalculateExpensiveValue()); 
+0

好的,當我有機會時,我會嘗試一下,讓你知道我喜歡它。你回答幾乎所有我的問題....我感謝它!大聲笑。 – cchampion 2010-02-11 22:05:01

+0

這是關於這個問題的主題,但你使用什麼單元測試框架的網點?不幸的是,我的公司沒有爲他們的網絡項目進行單元測試,我會開始把它們放在那裏。謝謝。 – cchampion 2010-02-12 17:23:34

+0

@cchampion:我個人使用NUnit,但有很多選擇。 – 2010-02-12 18:10:08

1

只是對靜態日誌輔助函數評論...

如果使用LogHelper功能像你建議,你就會失去記錄的調用站點信息的能力。

所以,如果你有靜態輔助類這樣的(撇開推遲消息參數的評價):

public class LogHelper 
{ 
    public static Info(ILog log, Object message) 
    { 
      if(log.IsInfoEnabled) 
      { 
      log.Info(message); 
      } 
    } 
} 

並且你使用這樣的:

public class MyClass 
{ 
    ILog logger = LogManager.GetLogger(<blah blah>); 
    public void MyFunc() 
    { 
    logger.Info("Hello!"); 
    } 
} 

如果您打開「呼叫站點」日誌記錄,呼叫站點信息將來自您的幫助器類:LogHelper.Info而不是您的真實類別MyClass.MyFunc

如果不依賴於記錄呼叫站點信息,這可能無關緊要。