Когда использовать директивы препроцессора в .net? - PullRequest
24 голосов
/ 19 ноября 2010

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

Так что я посмотрел на пример msdn здесь этоимеет код:

#define DEBUG
// ...
#if DEBUG
    Console.WriteLine("Debug version");
#endif

Мои два вопроса:

  • в приведенном выше примере, почему они определяют DEBUG?У меня сложилось впечатление, что это было установлено, если вы компилируете в режиме отладки v. Release?
  • , глядя на другой пример, в котором есть #define MYTEST, и затем пишет в консоль в зависимости от того, «определено» ли это, но какэто отличается от просто использования переменной?Что мне здесь не хватает?

Ответы [ 7 ]

17 голосов
/ 19 ноября 2010

Я бы действительно рекомендовал использовать условный атрибут вместо встроенных операторов #if.

[Conditional("DEBUG")]
private void DeleteTempProcessFiles()
{
}

Мало того, что это чище и легче для чтения, так как в вашем коде нет #if, #else. Этот стиль менее подвержен ошибкам как при обычном редактировании кода, так и при ошибках логического потока.

8 голосов
/ 19 ноября 2010

Как правило, дополнительные / условные символы компиляции будут предоставлены сценарием сборки.Очень редко можно увидеть #define, за исключением очень кода отладки (если вы понимаете, о чем я).

Повторное использование переменной;Я часто использую такие условия для обработки кода, который должен выполняться в разных средах выполнения (mono, cf, silverlight и т. Д.).Переменная не может быть достаточной, потому что код нельзя скомпилировать для неверной платформы (отсутствующие типы / методы и т. Д.).

В представленном примере я, вероятно, просто использовал бы Debug.WriteLine;так как он украшен [Conditional("DEBUG")], все вызовы к нему автоматически удаляются, если DEBUG не определен при сборке.

5 голосов
/ 19 ноября 2010

в приведенном выше примере, почему они определяют DEBUG? У меня сложилось впечатление, что было установлено, если вы компилируете в режиме debug v. Release?

Возможно, потому что это пример кода. Он предназначен для демонстрации работы #ifdef и друзей. Я бы не ожидал, что вы будете определять подобные символы в исходных файлах, если только это не для быстрого теста.

глядя на другой пример, который имеет "#define MYTEST" и затем записывает в консоль в зависимости от того, "определен ли он", но как это отличается от простого использования переменной? Что мне здесь не хватает?

Если MYTEST не определен во время компиляции, компилятор фактически не выдаст код между блоками #if и #endif. Поэтому результирующий IL будет меньше.

Также обратите внимание, что эти не являются директивами препроцессора в C #.

4 голосов
/ 19 ноября 2010

Я хотел бы привести один пример, в котором я использовал директиву препроцессора в моем проекте.

Моя программа создает много промежуточных файлов на диске.Я использовал директиву #DEBUG для удаления этих файлов, только если мой проект находится в режиме выпуска, в противном случае я сохраняю эти файлы, чтобы мы могли просматривать эти промежуточные файлы и определять, что происходит внутри.Сервер, я создаю проект в режиме выпуска, поэтому эти файлы будут удалены после завершения обработки.

#if (DEBUG==false)
    deleteTempFiles()
#endif
4 голосов
/ 19 ноября 2010

Если вы используете переменную, весь ваш код компилируется, когда вы используете директивы препроцессора, только часть кода, включенная в исполняемый файл / dll.

2 голосов
/ 19 ноября 2010

У меня есть код, который требует другой обработки при использовании среды Mono вместо CLR - таким образом, у меня есть директива Mono в некоторых из моих модулей. Я думаю, что это лучший пример, чем отладка

1 голос
/ 14 марта 2014

Я использовал это для многих вещей. Отладочные сообщения, которые я хочу только в отладочных сборках; очистить временные файлы; включить диагностические функции или действия.

...