Компилятор C # csc.exe
и сам язык C # не предоставляют никаких предопределенных констант для условной компиляции . Visual Studio добавляет только значения DEBUG
и TRACE
, которые можно настроить в среде IDE.В среде IDE также можно добавлять собственные произвольные символы, но, поскольку они являются по существу фиксированными (инвариантными) значениями, возможности ограничены.
Более мощные пользовательские параметры можно настроить, отредактировав проект .csproj
вручную.файл.Вы можете установить условия здесь для выборочного распространения символов условной компиляции в C # на основе огромного количества информации о среде и конфигурации, доступной в MSBuild (см. здесь и здесь , но в принципе не может быть полного списка, поскольку разрозненные компоненты произвольно предоставляют метаданные ad-hoc ).
Давайте рассмотримрабочий пример.Один из случаев, когда полезно условно компилировать, - это если вы хотите написать код, который адаптируется к любым инструментам, обнаруженным во время сборки.Таким образом, вы можете использовать новейшие языковые функции, сохраняя при этом возможность компилирования на компьютерах с более старыми инструментами, которые, как и ожидалось, отклоняли бы чужой синтаксис и / или ключевые слова.Для конкретного случая C # 7.0 в Visual Studio 2017 мы можем изменить .csproj
следующим образом:
.csproj файл (отрывок):
Вы также можете идентифицировать каждый из более старых компиляторов C #, постепенно снижая качество.То же самое касается обнаружения версии .NET Framework (часто запрашивается в StackOverflow [1] [2] [3] [4] ) и любые другие условия окружающей среды.Это оставлено в качестве упражнений для читателя, но в случае, если вы хотите скопировать / вставить выделенные строки сверху, вот текстовая версия.В качестве обновления снимка экрана я добавил здесь условные выражения в кавычки (хотя, казалось, что все работает без них)
<DefineConstants Condition="'$(VisualStudioVersion)'=='15'">CSHARP7</DefineConstants>
<!-- ... -->
<DefineConstants>DEBUG;TRACE;$(DefineConstants)</DefineConstants>
<!-- ... -->
<DefineConstants>TRACE;$(DefineConstants)</DefineConstants>
В любом случае, теперь вы можете написать условный C #код с использованием #if… #elif… #else… #endif
.Продолжая пример, в приведенном ниже коде используется новый синтаксис кортежа - доступный только в C # 7 - для замены элементов массива.Кстати, версия кортежа не только более лаконична и / или элегантна;он также производит отличный код IL:
#if CSHARP7
(rg[i], rg[j]) = (rg[j], rg[i]); // swap elements: tuple syntax
#else
var t = rg[i]; // swap elements: clunky
rg[i] = rg[j];
rg[j] = t;
#endif
Обратите внимание, что Visual Studio
IDE действительно правильно обрабатывает ваши настройки .csproj
вручную во всех отношениях.Учитывая .csproj
, который я показал ранее, редактор кода IDE правильно распознает и оценивает условную компиляцию для целей IntelliSense
, refactoring
, "неактивных" неактивных блоков кода и т. Д.
Iтакже упомянул, что MSBuild
имеет сокровищницу доступной информации, из которых $(VisualStudioVersion)
был только одним примером.К сожалению, нелегко узнать, какие значения доступны и какие они могут иметь во время сборки.Хитрость заключается в том, чтобы временно поместить проект C++
в ваше решение Visual Studio
(если у вас его еще нет) вместе с проектом C #.Если вы щелкните правой кнопкой мыши свойства проекта для этого .vcxproj
и затем посмотрите (например) «Дополнительные каталоги включения» на странице C/C++
, в правом нижнем углу появится раскрывающееся меню, когда вы нажмете для редактирования.:
Вы получите диалоговое окно с кнопкой «Макросы», которую можно нажать, чтобы получить список всех доступных MSBuild
переменные плюс их ожидаемые значения в соответствии с платформой и конфигурацией, которые в данный момент выбраны в IDE.Не пропустите поля хорошо известные метаданные элемента (с префиксом %
) внизу списка.
Вы можете получить представление о том, сколько вещей здесь, по размеру большого пальца полосы прокрутки на этом скриншоте.(Они перечислены в алфавитном порядке, я просто прокрутил эту часть раздела «P», потому что там было минимальное количество личной информации).Однако важно отметить, что как (доступные) переменные, так и их значения меняются с течением времени в ходе сборки, поэтому в этом списке вы можете найти элементы, которые недоступны для .csproj
ввремя обработки .
[edit:] Еще один способ узнать, какие значения свойств доступны во время и во время процесса сборки, - установить для MSBuild «подробность вывода» значение «Подробно»и затем восстановить.
После завершения сборки проверьте верхнюю часть журнала сборки в Visual Studio Окно вывода , и вы увидите список доступных имен свойств вместе с их начальными значениями.