C# &引用;“仅调试”;只应在以下情况下运行的代码;已打开";

C# &引用;“仅调试”;只应在以下情况下运行的代码;已打开";,c#,debugging,preprocessor,C#,Debugging,Preprocessor,我想添加一些C#“仅调试”代码,这些代码仅在调试人员请求时运行。在C++中,我曾经做过类似于以下的事情: void foo() { // ... #ifdef DEBUG static bool s_bDoDebugOnlyCode = false; if (s_bDoDebugOnlyCode) { // Debug only code here gets executed when the person debugging // manua

我想添加一些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#中实现这一点的最佳方法是什么

  • 我应该使用带有C#预处理器指令(
    #if/#endif DEBUG
    )的私有类静态字段吗
  • 我应该使用条件属性(保存代码),然后使用私有类静态字段(,由C#预处理器指令
    #if/#endif DEBUG
    ?)包围)
  • 还有别的吗

  • 一个实例变量可能是实现您想要的功能的方法。您可以将其设置为静态,以便在程序的生命周期(或线程,具体取决于静态内存模型)中保持相同的值,或者将其设置为普通实例变量,以便在对象实例的生命周期中对其进行控制。如果该实例是单例实例,则它们的行为方式相同

    #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
     // ...
    }
    
    完整地说,pragma(预处理器指令)被认为是控制程序流的一个小麻烦。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执行主机进行切换,并且在发布版本中,它的值无关紧要,因此它是无害的。

    您要寻找的是

    [ConditionalAttribute("DEBUG")]
    
    属性

    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.
      }    
      // ...
    }
    
    例如,如果您编写如下方法:

    [ConditionalAttribute("DEBUG")]
    public static void MyLovelyDebugInfoMethod(string message)
    {
        Console.WriteLine("This message was brought to you by your debugger : ");
        Console.WriteLine(message);
    }
    
    您在自己的代码中对此方法的任何调用都将仅在调试模式下执行。如果您在发布模式下构建项目,甚至对“MyLovelyDebugInfoMethod”的调用都将被忽略并从二进制文件中转储


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

    如果您想知道是否在调试,请在程序中的任何地方。 用这个

    声明全局变量

    bool isDebug=false;
    
    创建用于检查调试模式的函数

    [ConditionalAttribute("DEBUG")]
        public static void isDebugging()
        {
            isDebug = true;
        }
    
    在initialize方法中,调用函数

    isDebugging();
    
    现在在整个节目中。您可以检查调试并执行操作。
    希望这有帮助

    如果您只需要在将调试器连接到进程时运行代码,则可以尝试此操作

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

    我认为值得一提的是,
    [ConditionalAttribute]
    位于
    System.Diagnostics中名称空间。当我遇到以下情况时,我有点绊倒了:

    错误2找不到类型或命名空间名称“ConditionalAttribute”(是否缺少using指令或程序集引用?


    在第一次使用它之后(我认为它应该在
    系统中
    )。

    最后——一个阅读了整个问题的人。谢谢,好吧——这似乎是一个很长的解决方案(必须有两个预处理器部分),但也许这是C#能为我想要的做的最好的了。我不会因为你增加了两行预处理器指令就认为这很冗长。非常感谢Patrick,他否决了一个3年前接受的答案,而支持了一个不能解决整个问题的答案。条件属性仅阻止在非调试模式下执行方法。OP不仅希望如此,还希望能够使用调试器“打开”代码。而且,使用的gokkor标记不会编译。请注意,预处理器会告诉您程序是否在调试模式下编译,但不知道调试器是否正在实际运行。AFAIK:这和它的变体是唯一确定是否使用调试标志集编译了程序wash的方法。如果您试图确定它是否编译为DEUBG:
    #if debug public const bool debuging=true#else public const bool Debuging=错误#endif
    Guess不建议在评论中添加一些代码。谢谢!这正是我想要的:在最后添加一个Console.ReadLine(),以防止在调试时关闭控制台窗口。使用Attribute时,不必编写后缀“Attribute”。条件=条件属性。属性类应该以“attribute”结尾,但在代码中用作属性时可以省略。省略后缀更容易阅读。