Почему Debug.WriteLine не работает без константы DEBUG?

Я столкнулся с проблемой, когда кто-то, по-видимому, отключил DEBUG а также TRACE константы в проекте C# .NET, над которым я работал, поэтому мои звонки Debug.WriteLine не имели никакого эффекта. (Вывод отладки не был показан в выводе.) После повторного включения их, как описано здесь, я начал видеть свой вывод.

Знать, как это исправить, полезно, но мой вопрос - почему? Насколько я понимаю, DEBUG является постоянной времени компиляции, а Debug Класс уже скомпилирован, когда я строю свой проект. Так как же мои звонки Debug.WriteLine пропускаются; не должны ли они быть скомпилированы, как весь мой другой код?

Я могу придумать несколько возможных способов, которыми это могло бы произойти:

  • MS реализовала некоторую специальную "функцию" в компиляторе, чтобы удалить эти вызовы без постоянной
  • Visual Studio настраивает отладчик так, чтобы он выполнял или не слушал на основе этого параметра проекта для вывода отладки при запуске
  • Debug имеет какой-то сумасшедший код, который проверяет вызывающую сборку для какого-то флага, установленного во время компиляции

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

Итак, как это работает?

2 ответа

Решение

Посмотрите на атрибут Conditional... Он вызывает игнорирование вызова метода во время JIT, если указанный символ не определен. Большинство методов System.Diagnostic.Debug определяются с использованием этого атрибута и значения "DEBUG" (см., Например, справочный источник), поэтому вызовы не происходят, если символ DEBUG не определен во время JIT.

Debug.WriteLine(..) вызовы удаляются компилятором, если константа DEBUG не установлена ​​во время компиляции кода.

Один из способов симулировать это в вашем коде - использовать #if DEBUG, например:

#if DEBUG 
    // This portion of the code will only exist in code compiled with the DEBUG constant set.
#end if

Другой способ - добавить ConditionalAttribute[Conditional("DEBUG")] к вершине ваших методов, что делает класс Debug для WriteLine(..),

Точные подробности можно найти по следующей ссылке на MSDN в документации ConditionalAttribute: https://msdn.microsoft.com/en-us/library/system.diagnostics.conditionalattribute(v=vs.110).aspx

Другие вопросы по тегам