如何在c#中重构log4net语句?

时间:2010-02-11 21:50:58

标签: c# logging refactoring log4net

好的,在阅读了danben对这个post的回答后,我想我已经确信需要编写这种代码,至少在很多情况下都是如此。我的经理似乎也同意。

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

它的问题在于让我看到所有这些if语句放在任何地方只是为了做一个简单的日志语句。

我的问题是,如何在不重现必须评估日志方法参数的性能问题的情况下将其重构为类?

简单地将它作为静态方法放在一个类中没有用,因为当你传递Object消息时,它仍然需要评估参数:

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

C#显然不支持强制方法为内联,因此该解决方案不可用。 C#不支持MACRO。我们能做什么?!?!

更新: 感谢您的回复,我没有忘记这一点;现在我的名单上只是低位优惠。一旦我陷入困境,我会接受它并给出答案。感谢。

另一个更新:
好吧......我还没有看好这个,你们两个都应该得到正确答案;但我向Tanzelax颁发了答案,因为我同意,我认为他们会自动内联。他发布的链接很好地说服了我,我现在不应该过多担心这一点,这也很好。我以后还会看看那些lambda的东西。谢谢你的帮助!

3 个答案:

答案 0 :(得分:15)

一个简单的解决方案是使用lambda表达式有效地将消息生成推迟到需要时,如果需要它:

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

用以下方式调用:

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

答案 1 :(得分:3)

如果静态辅助方法很简单,它应该自动内联,并且具有匹配的性能。

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

答案 2 :(得分: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

如果您不依赖于记录呼叫站点信息,那可能并不重要。