1

C# 不支持 C/C++ 宏。StackOverflow 中有很多与此相关的问答,但我找不到特定问题的答案。

假设我正在使用http://logging.apache.org/log4net/release/faq.html建议的代码:

if(log.IsDebugEnabled) 
{
    log.Debug("Entry number: " + i + " is " + entry[i]);
}

这种启用/禁用日志记录的方式有明显的缺点。在 C++ 中,我会使用像 LOG(expr) 这样的宏来提高代码的可读性并更好地控制代码的“if(log.IsDebugEnabled)”部分(这可能在项目中重复数千次)。

如何在 C# 中实现 LOG(expr) - 类似结果?

谢谢!

4

6 回答 6

3

你不能……因为 C# 没有宏!

当然,您可以这样做:

定义采用 lambda 的 log 函数

void Log(Func<string> f) {
  if(log.IsDebugEnabled) 
  {
    log.Debug(f());
  }
}

当你想记录一些东西时这样调用它:

Log(()=>"Entry number: " + i + " is " + entry[i]);

这样,仅在启用日志记录时才评估该参数,我认为这是您想要实现的。

(我的 C# 有点生疏,所以语法可能会有些偏差)

于 2012-10-25T08:09:41.330 回答
1

您可以将其定义为方法并将其标记为有条件的调试器:

internal static SomeClass
{
    [Conditional("DEBUG")] 
    internal static void Log(string expr)
    {
     //...
    }
}

如果未定义编译器常量“DEBUG”,编译器将删除此方法以及对该方法的任何调用或引用。是的,它也适用于其他人。它类似于:

internal static SomeClass
{
    #if DEBUG
    internal static void Log(string expr)
    {
     //...
    }
    #endif
}

但是使用它不会删除对这个方法的引用,所以你也必须包装它们。


是的,这只允许在编译时禁用日志。jalf更好的方法在运行时处理这个问题。

于 2012-10-25T08:08:11.793 回答
1

请改用新的 log4netXXXXFormat方法。它们是这样实现的:

public virtual void DebugFormat(string format, params object[] args)
{
    if (this.IsDebugEnabled)
    {
       this.Logger.Log(declaringType, m_levelDebug, String.Format(format, args));
    }
}

此外,您将拥有String.Format而不是简单的字符串连接的权力

log.DebugFormat("Entry number: {0} is {1}", i, entry[i]);
于 2012-10-25T09:01:51.583 回答
0

作为一个想法,您可以使用一个静态方法创建类,该方法将接受字符串表达式。

于 2012-10-25T08:06:36.947 回答
0

...部分代码(可能在项目中重复数千次)。

每当你在想这样的事情时,首先应该在你脑海中浮现的就是封装,封装,封装

你可以简单地创建你自己的 Logger 类,它有一个IsDebugEnabled属性和你自己的Log方法。

void Log( string message )
{
  if ( IsDebugEnabled ) 
  {
     log.Debug( message );
  }
}

可能更好地寻找现有的记录器库,它们可能已经支持您需要的所有功能。

例如log4net

于 2012-10-25T08:07:33.573 回答
-1

面向方面的编程是您想要的,因为日志记录和缓存之类的事情与您的业务逻辑关系不大。所以他们应该分开。

有很多可用的框架,看看 postsharp(http://www.sharpcrafters.com/) 或 snap (http://www.simpleaspects.com/)。如果您使用受支持的依赖注入框架之一,也许 snap 是不错的选择。

更新:如果你使用 log4net,你应该可以从配置文件中关闭它,<log4net threshold="OFF" />所以你应该有一个调试配置和一个发布配置

于 2012-10-25T08:22:16.647 回答