Условная компиляция в зависимости от версии фреймворка в C#

Существуют ли какие-либо символы препроцессора, которые позволяют что-то вроде

#if CLR_AT_LEAST_3.5
// use ReaderWriterLockSlim
#else
// use ReaderWriterLock
#endif

или каким-то другим способом это сделать?

Обратите внимание, что IIRC это относится только к обычный 3.5, но не к CF 3.5 - вы можете захотеть назвать любые символы соответствующим образом.

Marc Gravell 03.01.2009 14:29
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
25
1
9 297
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Ответ принят как подходящий

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

  1. Создайте разные конфигурации вашего проекта, по одной для каждой версии CLR, которую вы хотите поддерживать.

  2. Выберите такой символ, как VERSION2, VERSION3 и т. д. Для каждой версии CLR.

  3. В каждой конфигурации определите один связанный с ним символ и отмените определение всех остальных.

  4. Используйте эти символы в блоках условной компиляции.

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

Вы можете использовать отражение для динамической проверки наличия определенного типа, такого как ReaderWriterLockSlim (вместо использования препроцессора).

Это даст вам преимущество в том, что вы можете развернуть одну версию вашего продукта, а пользователи, имеющие (или обновляющиеся) .NET 3.5, получат выгоду от оптимизированного кода.

Но это сделало бы его настоящей свиньей ... выполнимым, но не очень привлекательным. В частности, некоторые функции .NET 3.5 (например, Expression) было бы трудно использовать с помощью очень с помощью отражения.

Marc Gravell 03.01.2009 14:26

Марк, я бы не использовал отражение во всем коде, просто чтобы проверить, доступна ли определенная библиотека / тип на клиентской машине. Это было бы очень похоже на символы препроцессора (то есть условие if, а затем ветвление в зависимости от того, есть ли 3.5 или нет)

Dirk Vollmar 03.01.2009 14:30

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

Alexey Romanov 03.01.2009 15:32

Встроенных нет, но вы можете поставить свои собственные.

Для этого конкретного сценария вы можете захотеть инкапсулировать логику (например) в класс-оболочку (блокировку), чтобы у вас не было #if, разбросанного по всему коду; конечно, если вы делаете лишь небольшую блокировку, это может не стоить хлопот.

Я использую разные конфигурации и / или проекты для сборки на различных платформах, например, сборки protobuf-net для .NET 2.0, .NET 3.0, mono, CF 2.0, CF 3.5 с использованием этого трюка. В коде есть блоки #if, основанные на различных символах для управления логикой - так, например, BinaryFormatter недоступен на CF, WCF доступен только с .NET 3.0, Delegate.CreateDelegate не на CF 2.0 и т. д.

Если это все, что вам нужно сделать, я полагаю, вы используете мог Environment.Version, но, как и решение диво, оно, похоже, оставляет там много ненужного кода.

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