Отладка только кода, который должен запускаться только при включении

Я хотел бы добавить некоторый код 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. Что-то другое?

person Matt Smith    schedule 22.02.2011    source источник


Ответы (5)


Переменная экземпляра, вероятно, будет способом делать то, что вы хотите. Вы можете сделать его статическим, чтобы сохранять одно и то же значение в течение всего срока службы программы (или потока, в зависимости от вашей модели статической памяти), или сделать его обычным экземпляром 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.
  }    
  // ...
}

Никаких прагм, намного чище. Обратной стороной является то, что Conditional может применяться только к методам, поэтому вам придется иметь дело с логической переменной, которая ничего не делает в сборке выпуска. Поскольку переменная существует исключительно для переключения с хоста выполнения VS, а в сборке релиза ее значение не имеет значения, оно довольно безвредно.

person KeithS    schedule 22.02.2011
comment
Наконец, кто-то, кто прочитал весь вопрос. Спасибо, хорошо - это казалось долгим решением (необходимость иметь две секции препроцессора), но, возможно, это лучшее, что C # может сделать для того, что я хочу. - person Matt Smith; 22.02.2011
comment
Мех. Я бы не назвал это длинным только потому, что вы добавили еще две строки директивы препроцессора. - person KeithS; 22.02.2011
comment
Что ж, большое спасибо, Патрик, за то, что проголосовал против принятого ответа 3-летней давности в пользу того, который не решает всей проблемы. Условный атрибут предотвращает выполнение метода только в режимах без отладки. OP хотел не только этого, но и возможности включить код с помощью отладчика. И тег gokkor в том виде, в котором он используется, не компилируется. - person KeithS; 19.11.2014
comment
Обратите внимание, что препроцессор сообщает вам, компилируется ли программа в режиме отладки, но не сообщает, действительно ли отладчик работает. - person Shane; 25.06.2018

Вы ищете

[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. Но это все вместе другой случай. Оставьте комментарий, если это то, что вы пытаетесь сделать.

person gokkor    schedule 10.07.2012
comment
При использовании атрибута вам не нужно писать атрибут суффикса. Условный = Условный атрибут. Класс атрибута должен заканчиваться атрибутом, но его можно опустить при использовании в качестве атрибута в коде. Легче читать, если опущен суффикс. - person Eric Ouellet; 26.04.2019

Вы можете попробовать это, если вам нужен только код для запуска, когда к процессу подключен отладчик.

if (Debugger.IsAttached)
{
     // do some stuff here
}
person Wes    schedule 19.06.2014
comment
Спасибо! Это именно то, что я хотел: сделать Console.ReadLine () в конце, чтобы предотвратить закрытие окна консоли при отладке. - person VVS; 14.12.2018

Думаю, стоит упомянуть, что [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).

person XyberICE    schedule 17.10.2014

Если вы хотите знать, есть ли отладка, везде в программе. Использовать этот.

Объявить глобальную переменную.

bool isDebug=false;

Создать функцию для проверки режима отладки

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

В методе инициализации вызовите функцию

isDebugging();

Теперь по всей программе. Вы можете проверить наличие отладки и выполнить операции. Надеюсь это поможет!

person Mohamed Alikhan    schedule 08.01.2014
comment
AFAIK: этот и его варианты - единственный верный способ узнать, скомпилирована ли программа с установленным флагом отладки. - person LosManos; 14.04.2015
comment
Метод отладки is не нужен, если вы пытаетесь определить, был ли он скомпилирован как DEUBG: #if DEBUG public const bool debuuging = true; #else public const bool debuuging = false; #endif - person Dr Jeff Sinclair; 06.05.2021
comment
Думаю, не рекомендуется добавлять в комментарий небольшой фрагмент кода. - person Dr Jeff Sinclair; 06.05.2021