仅在“打开”时才运行的“仅调试”代码


93

我想添加一些仅在调试人员要求时运行的C#“仅调试”代码。在C ++中,我曾经做过类似以下事情:

void foo()
{   
  // ...
  #ifdef DEBUG
  static bool s_bDoDebugOnlyCode = false;
  if (s_bDoDebugOnlyCode)
  {
      // Debug only code here gets executed when the person debugging 
      // manually sets the bool above to true.  It then stays for the rest
      // of the session until they set it to false.
  }
  #endif
 // ...
}

由于没有局部静态变量,因此我无法在C#中完全相同。

问题:用C#完成此操作的最佳方法是什么?

  1. 是否应该在C#预处理程序指令(#if/#endif DEBUG)中使用私有类静态字段?
  2. 我应该使用Conditional属性(以保存代码),然后使用私有类静态字段(被C#预处理程序指令包围#if/#endif DEBUG吗?)。
  3. 还有吗

Answers:


145

实例变量可能是您要执行的操作的方式。您可以使它在程序(或线程,取决于您的静态内存模型)的生命周期中保持相同的值,以使其保持静态,或者使它成为普通实例var,以在对象实例的生命周期内对其进行控制。如果该实例是单例,则它们的行为将相同。

#if DEBUG
private /*static*/ bool s_bDoDebugOnlyCode = false;
#endif

void foo()
{   
  // ...
#if DEBUG
  if (s_bDoDebugOnlyCode)
  {
      // Code here gets executed only when compiled with the DEBUG constant, 
      // and when the person debugging manually sets the bool above to true.  
      // It then stays for the rest of the session until they set it to false.
  }
#endif
 // ...
}

只是为了完整起见,编译指示(预处理器指令)被认为有点麻烦,可以用来控制程序流。.NET使用“ Conditional”属性可以解决此问题的一半。

private /*static*/ bool doDebugOnlyCode = false; 
[Conditional("DEBUG")]
void foo()
{   
  // ...    
  if (doDebugOnlyCode)
  {
      // Code here gets executed only when compiled with the DEBUG constant, 
      // and when the person debugging manually sets the bool above to true.  
      // It then stays for the rest of the session until they set it to false.
  }    
  // ...
}

没有杂物,更清洁。缺点是条件式只能应用于方法,因此您必须处理布尔变量,该变量在发布版本中不做任何事情。由于该变量只存在于VS执行主机中,而在发行版中,其值无关紧要,因此它是无害的。


2
最后-读完整个问题的人。谢谢,好吧-这似乎是一个冗长的解决方案(必须有两个预处理程序部分),但也许这是C#可以做的最好的工作。
马特·史密斯

6
嗯 我不会这么冗长,因为您还要添加两行预处理器指令。
KeithS

4
很好,非常感谢Patrick,对3岁的已接受答案的投票否决了一个无法解决整个问题的答案。条件属性仅阻止方法在非调试模式下执行。OP不仅希望这样做,而且希望能够使用调试器“打开”代码。而且,gokkor使用的标记将无法编译。
KeithS 2014年

2
请注意,预处理器会告诉您程序是否在调试模式下进行编译,但不会告知调试器是否正在实际运行。
Shane

65

您正在寻找的是

[ConditionalAttribute("DEBUG")]

属性。

例如,如果您编写类似的方法:

[ConditionalAttribute("DEBUG")]
public static void MyLovelyDebugInfoMethod(string message)
{
    Console.WriteLine("This message was brought to you by your debugger : ");
    Console.WriteLine(message);
}

您在自己的代码中对此方法的任何调用都只会在调试模式下执行。如果您以发布模式构建项目,则即使调用“ MyLovelyDebugInfoMethod”,也会被忽略并从二进制文件中转储出去。

哦,还有另一件事,如果您试图确定执行时当前是否正在调试代码,则还可以检查当前进程是否被JIT钩住了。但这是另一种情况。如果您要这样做,请发表评论。


3
使用属性时,不必写后缀“ Attribute”。条件= ConditionalAttribute。属性类应以“ Attribute”结尾,但在代码中用作属性时可以省略。省略后缀后,阅读起来会更容易。
Eric Ouellet

23

如果仅在将调试器附加到进程时才需要运行代码,则可以尝试此操作。

if (Debugger.IsAttached)
{
     // do some stuff here
}

谢谢!这正是我想要的:在末尾执行Console.ReadLine()以防止在调试时关闭控制台窗口。
VVS

4

我认为可能值得一提的[ConditionalAttribute]是在System.Diagnostics;名称空间中。当我得到时,我迷迷糊糊了:

Error 2 The type or namespace name 'ConditionalAttribute' could not be found (are you missing a using directive or an assembly reference?)

首次使用后(我认为它应该在中System)。


3

如果您想知道是否进行调试,请在程序中无处不在。用这个。

声明全局变量。

bool isDebug=false;

创建用于检查调试模式的功能

[ConditionalAttribute("DEBUG")]
    public static void isDebugging()
    {
        isDebug = true;
    }

在初始化方法中调用函数

isDebugging();

现在在整个程序中。您可以检查调试并进行操作。希望这可以帮助!


1
据我所知:这个和变种本文仅安全可靠的方式知道如果一个程序洗编译与调试标志设置。
LosManos
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.