2010-02-11 57 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

如果不依赖于记录呼叫站点信息,这可能无关紧要。