Есть несколько незначительных мест, где код моего проекта можно было бы значительно улучшить, если бы целевая платформа была более новой версией. Я хотел бы иметь возможность лучше использовать условную компиляцию на C #, чтобы переключать их по мере необходимости.
Что-то вроде:
#if NET40
using FooXX = Foo40;
#elif NET35
using FooXX = Foo35;
#else NET20
using FooXX = Foo20;
#endif
Есть ли какие-нибудь из этих символов бесплатно? Нужно ли мне вводить эти символы как часть конфигурации проекта? Это кажется достаточно простым, так как я буду знать, на какой фреймворк нацелено из MSBuild.
/p:DefineConstants="NET40"
Как люди справляются с этой ситуацией? Вы создаете разные конфигурации? Вы передаете константы через командную строку?
Ответы:
Один из лучших способов добиться этого - создать в вашем проекте различные конфигурации сборки:
И в одной из ваших конфигураций по умолчанию:
Что установило бы значение по умолчанию, если бы оно не было определено в другом месте. В приведенном выше случае OutputPath будет предоставлять вам отдельную сборку при каждой сборке каждой версии.
Затем создайте цель AfterBuild для компиляции различных версий:
В этом примере будет перекомпилирован весь проект с переменной Framework, установленной на NET20 после первой сборки (компилируем обе и предполагаем, что первая сборка была NET35 по умолчанию, приведенной выше). Каждая компиляция будет иметь правильные значения условного определения.
Таким образом вы даже можете исключить определенные файлы из файла проекта, если хотите, чтобы без #ifdef файлов:
или даже ссылки
источник
Альтернатива, которая работает у меня до сих пор, - добавить в файл проекта следующее:
Это принимает значение свойства TargetFrameworkVersion, которое похоже на «v3.5», заменяет «v» и «». чтобы получить "NET35" (с помощью новой функции функций свойств ). Затем он удаляет любое существующее значение «NETxx» и добавляет его в конец DefinedConstants. Возможно, это удастся упростить, но у меня нет времени возиться.
Посмотрев на вкладку Build свойств проекта в VS, вы увидите результирующее значение в разделе условных символов компиляции. При изменении версии целевой платформы на вкладке «Приложение» символ автоматически изменяется. Затем вы можете использовать
#if NETxx
директивы препроцессора обычным образом. Изменение проекта в VS, похоже, не теряет настраиваемую PropertyGroup.Обратите внимание, что это, похоже, не дает вам ничего другого для целевых параметров профиля клиента, но для меня это не проблема.
источник
У меня были проблемы с этими решениями, возможно, потому, что мои исходные константы были заранее созданы этими свойствами.
Visual Studio 2010 также выдавала ошибку из-за точек с запятой, утверждая, что они являются недопустимыми символами. Сообщение об ошибке подсказывало мне, как я мог видеть предварительно созданные константы, разделенные запятыми, за которыми в конечном итоге следовала моя «недопустимая» точка с запятой. После некоторого переформатирования и массажа я смог найти решение, которое мне подходит.
Я бы разместил снимок экрана с диалоговым окном «Дополнительные параметры компиляции» (открываемым нажатием кнопки «Дополнительные параметры компиляции ...» на вкладке «Компиляция» вашего проекта). Но как новому пользователю мне не хватает репутации для этого. Если бы вы могли видеть снимок экрана, вы бы увидели, что пользовательские константы автоматически заполняются группой свойств, а затем вы бы сказали: «Мне нужно кое-что из этого».
РЕДАКТИРОВАТЬ: Получил эту репутацию на удивление быстро .. Спасибо, ребята! Вот этот снимок экрана:
источник
Начнем с очистки констант:
Затем создайте свои отладочные, трассировочные и другие константы, например:
Наконец, создайте константы вашего фреймворка:
Считаю такой подход очень читабельным и понятным.
источник
В файле .csproj после существующей
<DefineConstants>DEBUG;TRACE</DefineConstants>
строки добавьте следующее:Сделайте это для конфигураций сборки как отладки, так и выпуска. Затем используйте в своем коде:
источник
@Azarien, ваш ответ можно объединить с ответом Джереми, чтобы сохранить его в одном месте, а не Debug | Release и т. Д.
Для меня лучше всего работает сочетание обоих вариантов, т.е. включение условий в код с использованием #if NETXX, а также сборка для разных версий фреймворка за один раз.
В моем файле .csproj есть:
и в целях:
источник
Если вы используете систему сборки .NET Core, вы можете использовать ее предопределенные символы (которые фактически уже соответствуют вашему примеру и не требуют каких-либо изменений в вашем
.csproj
!):Список предопределенных символов задокументирован в разделе Разработка библиотек с помощью кроссплатформенных инструментов и #if (Справочник по C #) :
источник