Существуют ли какие-либо символы препроцессора, которые позволяют что-то вроде
#if CLR_AT_LEAST_3.5
// use ReaderWriterLockSlim
#else
// use ReaderWriterLock
#endif
или каким-то другим способом это сделать?





Я не думаю, что есть какие-то предопределенные символы препроцессора. Однако вы можете добиться того, чего хотите, вот так:
Создайте разные конфигурации вашего проекта, по одной для каждой версии CLR, которую вы хотите поддерживать.
Выберите такой символ, как VERSION2, VERSION3 и т. д. Для каждой версии CLR.
В каждой конфигурации определите один связанный с ним символ и отмените определение всех остальных.
Используйте эти символы в блоках условной компиляции.
Вы можете вручную установить этот символ с помощью / определить переключатель компилятора. Затем вы создаете разные конфигурации сборки для каждой желаемой версии clr.
Вы можете использовать отражение для динамической проверки наличия определенного типа, такого как ReaderWriterLockSlim (вместо использования препроцессора).
Это даст вам преимущество в том, что вы можете развернуть одну версию вашего продукта, а пользователи, имеющие (или обновляющиеся) .NET 3.5, получат выгоду от оптимизированного кода.
Но это сделало бы его настоящей свиньей ... выполнимым, но не очень привлекательным. В частности, некоторые функции .NET 3.5 (например, Expression) было бы трудно использовать с помощью очень с помощью отражения.
Марк, я бы не использовал отражение во всем коде, просто чтобы проверить, доступна ли определенная библиотека / тип на клиентской машине. Это было бы очень похоже на символы препроцессора (то есть условие if, а затем ветвление в зависимости от того, есть ли 3.5 или нет)
Очевидно, вам нужно будет кэшировать любые результаты отражения, если вы пойдете по этому пути.
Встроенных нет, но вы можете поставить свои собственные.
Для этого конкретного сценария вы можете захотеть инкапсулировать логику (например) в класс-оболочку (блокировку), чтобы у вас не было #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, но, как и решение диво, оно, похоже, оставляет там много ненужного кода.
Обратите внимание, что IIRC это относится только к обычный 3.5, но не к CF 3.5 - вы можете захотеть назвать любые символы соответствующим образом.