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

发布于 2024-08-21 03:44:58 字数 988 浏览 7 评论 0原文

好的,在阅读 danben 对此的回答后 post,我想我确信有必要编写这种代码,至少在很多情况下是这样。我的经理似乎也同意这一点。

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

它的问题是,看到所有这些 if 语句放置在各处只是为了执行一个简单的日志语句,这让我感到非常烦恼。

我的问题是,我们如何将其重构为一个类,而不重现必须评估 log 方法的参数的性能问题?

简单地将其作为静态方法放入类中并没有帮助,因为当您传递 Object 消息时,它仍然必须评估参数:

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

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

更新: 谢谢各位的回复,我没有忘记这个问题;它现在在我的列表中只是低优先级。一旦我有点陷入困境,我就会开始并给出答案。谢谢。

另一个更新:
好吧……我还没有仔细研究过这个问题,你们俩都应该得到正确的答案;但我给了 Tanzelax 答案,因为我同意,我认为它们会自动内联。他发布的链接很好地说服了我,我现在不必太担心这个问题,这也很好,哈哈。稍后我还会看看那些 lambda 的东西。感谢您的帮助!

Ok so after reading danben's answer on this post, I guess I'm convinced of the need for writting this kind of code, atleast in a lot of cases. My managers seem to be agreeing too.

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

The problem with it is it bugs the heck out of me seeing all these if statements placed everywhere just to do a simple log statement.

My question is, how might we refactor this into a class without reproduceing the performance problem of having to evaluate the arguments to the log method?

Simply putting it in a class as a static method doesn't help, because when you pass the Object message it still has to evaluate the argument:

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

C# apparently doesn't support forcing a method to be inline, so that solution isn't available. MACROs are not supported in C#. What can we do?!?!

UPDATE:
Thanks for the replies, I have not forgot about this one; it's just low priorty on my list right now. I will get to it and award the answer once I get caught up a bit. Thanks.

Another UPDATE:
well ... I still haven't look at this closly yet, and both of you deserve the correct answer; but I awarded Tanzelax the answer because I agree, I think they will be automatically inlined. The link he posted does good job of convincing me I shouldn't worry too much about this right now, which is also good lol. I'll still look at those lambda things later. Thanks for the help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

网白 2024-08-28 03:44:58

一种简单的解决方案是使用 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());

One simple solution is to use lambda expressions to effectively defer the message generation until it's needed, if it's needed:

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

Call it with:

log.Info(() => "This is expensive: " + CalculateExpensiveValue());
素衣风尘叹 2024-08-28 03:44:58

如果静态帮助器方法那么简单,它应该自动内联,并且将具有匹配的性能。

C# 编译器或 JIT 在什么级别优化应用程序代码?

If the static helper method is that simple, it should be inlined automatically, and will have the performance to match.

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

内心旳酸楚 2024-08-28 03:44:58

只是关于静态日志助手函数的评论...

如果您像您建议的那样使用 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

如果您不依赖记录调用站点信息,这可能并不重要。

Just a comment about the static log helper function...

If you use a LogHelper function like you are proposing, you will lose the ability to log the call site info.

So, if you have the static helper class like this (leaving aside deferring the evaluation of the message parameters):

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

And you use it like this:

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

If you have "call site" logging turned on, the call site information will be from your helper class: LogHelper.Info rather than your real class MyClass.MyFunc.

That might not matter much if you don't rely on logging the call site information.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文