发布版本中的Debug.WriteLine

73

有没有一种方法可以在不定义DEBUG的情况下,在发布版本中使用Debug.WriteLine


8
在发布版中定义_DEBUG的副作用比你想象的要少得多。当你在解决发布版问题时,一定不要犹豫地定义它。 - Hans Passant
使用.NET跟踪(最好是TraceSources)。它更加灵活。 - user2864740
5个回答

63

4
完美。我只想使用SysInternals DebugViewer,而Trace.WriteLine似乎被它捕捉到了。 - Karsten

50

不。如果您没有定义DEBUG预处理器符号,则由于应用了[Conditional("DEBUG")]特性,编译器将删除任何对Debug.*的调用。

您可能想考虑使用Trace.WriteLine或其他日志记录技术。


21

虽然你仍然必须定义DEBUG - 但不需要在整个程序集中都这么做。你只需要在需要的源文件中定义即可。因此,如果你想从特定类中进行调试记录,只需为该源文件定义DEBUG即可。

#define DEBUG
using System.Diagnostics;

...

class Logger
{
    void Log( string msg ){ Debug.WriteLine( msg ); }
}

1
我最喜欢这种方法。#define仅适用于源文件,而不是整个项目。这是在nuget中发布库的好方法(比如说),当其他项目处于DEBUG模式时,可以重复使用它们来进行Debug.Writeline,并具有自定义结果,例如时间戳和异常处理等。 - Jezz Santos

5

是的。您可以使用TRACE,如上面的评论中所述,或者通过使用表达式树而不定义任何编译时常量。

        var p = Expression.Parameter(typeof(string), "text");
        var callExp =
            Expression.Call(
              typeof(System.Diagnostics.Debug).GetRuntimeMethod(
                   "WriteLine", new [] { typeof(string) }),
              p);
        Action<string> compiledAction = Expression.Lambda<Action<string>>(
                                         callExp, p)
                                         .Compile();

在此之后,您可以通过调用Debug.WriteLine随时调用它。

        compiledAction("Debug text");

你本质上是通过在运行时动态构建方法而不是调用静态方法来欺骗编译器。
由于该操作被编译并重复使用,因此没有性能损失。
这就是我在SharpLog中编写DebugLogger的方式。

如果你感兴趣,可以在这里查看源代码:https://github.com/prasannavl/SharpLog/blob/master/SharpLog/DebugLogger.cs


2
我不知道我是否会推荐这个..但这是一个“有趣”的解决方案。 - user2864740
一般情况下,我不会推荐这样做。但是如果生产代码本来就要打印调试值,那么使用Debug.WriteLine或编译后的Lambda都没有区别,后者几乎相当于(() => Debug.WriteLine()),只是没有JIT优化。 - user3513472

1

Debugger.Log(0, null, "Your string here"); 可以作为一种替代方案,它在Debug.Write内部使用,并且在Release模式下也能正常工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接