Условная компиляция в зависимости от версии платформы в C#
-
03-07-2019 - |
Вопрос
Существуют ли какие-либо символы препроцессора, которые позволяют что-то вроде
#if CLR_AT_LEAST_3.5
// use ReaderWriterLockSlim
#else
// use ReaderWriterLock
#endif
или какой-то другой способ сделать это?
Решение
Я не думаю, что существуют какие-либо предопределенные символы «препроцессора».Однако вы можете добиться того, чего хотите, следующим образом:
Создайте разные конфигурации вашего проекта, по одной для каждой версии CLR, которую вы хотите поддерживать.
Выберите символ, например
VERSION2
,VERSION3
и т. д.для каждой версии CLR.В каждой конфигурации определите один связанный с ним символ и отмените определение всех остальных.
Используйте эти символы в блоках условной компиляции.
Другие советы
Встроенных программ нет, но вы можете поставить свои.
В этом конкретном сценарии вы можете захотеть инкапсулировать логику (например) в классе-оболочке (блокировке), чтобы у вас не было необходимости #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 и т. д.
Вы можете использовать отражение, чтобы динамически проверять, доступен ли определенный тип, например ReaderWriterLockSlim (вместо использования препроцессора).
Это даст вам преимущество, заключающееся в том, что вы сможете развернуть одну версию своего продукта, а пользователи, имеющие .NET 3.5 (или обновляющиеся до нее), получат выгоду от оптимизированного кода.
Вы можете вручную установить этот символ, используя /определить переключатель компилятора.Затем вы создаете разные конфигурации сборки для каждой желаемой версии clr.
Если это все, что вам нужно было сделать, я полагаю, вы мог используйте Environment.Version, но например диво решение, похоже, там остается много ненужного кода.