Могу ли я создать директиву препроцессора, зависящую от версии .NET framework?
Вот конкретный пример того, что я хочу сделать.
Рассмотрим функцию string.Join
. Pre -.NET 4.0, было только две перегрузки, для которых требовался параметр string[]
.
Начиная с .NET 4.0, появляются новые перегрузки с использованием более гибких типов параметров, включая IEnumerable<string>
.
У меня есть библиотека, которая включает в себя функцию Join
, которая действительно выполняет функцию .NET 4.0 string.Join
. Мне просто интересно, могу ли я реализовать эту функцию в зависимости от целевой платформы .NET. Если 4.0, он может просто вызвать string.Join
внутренне. Если 3.5 или старше, он может назвать свою внутреннюю реализацию.
- Имеет ли смысл эта идея?
- Если это имеет смысл, какой самый логичный способ сделать это? Я предполагаю, что я просто предполагаю, что директива препроцессора будет иметь наибольший смысл, поскольку вызов
string.Join
с параметром IEnumerable<string>
даже не будет компилироваться при таргетинге на версию .NET старше 4.0; поэтому любой подход, который я использую, должен был состояться до компиляции. (Проверка свойства Environment.Version
во время выполнения, например, не будет работать.)
Ответы
Ответ 1
Вы можете взглянуть на другой вопрос о переполнении стека, который иллюстрирует, как установить условные константы в файле проекта XML:
Обнаружить версию рамочной платформы во время компиляции
Затем, используя это, вы можете определить, следует ли использовать перегрузки .NET 4 или собственную библиотеку.
Ответ 2
Да, я думаю, что это имеет смысл (для вашего конкретного случая, так как изменение относительно незначительное), хотя очевидно, что такая вещь может быстро выходить из-под контроля.
ИМХО, наиболее логичным путем было бы создание различных конфигураций решений/проектов для каждой версии, затем определение пользовательского символа (например, NET40
) в ваших конфигурациях 4.0, а затем использовать его с помощью #if
. Я не уверен, что конфигурации позволят вам изменить версию исполнения (что, очевидно, будет идеальным решением), но в худшем случае вам придется вручную менять версию.
EDIT: Я только видел ответ, связанный с ответом Джошуа, и это похоже на более оптимизированное решение, но я оставлю это здесь в любом случае, поскольку он, строго говоря, отвечает вопрос.
Ответ 3
Вы можете подготовить свой код для .NET 4.0 и написать аналогичный код для базы .NET 3.5 на обнаружении инфраструктуры.
#if NOT_RUNNING_ON_4
public static class GuidExtensions
{
public static bool TryParse(this string s, out Guid result)
{
if (s.IsNullOrEmpty())
return null;
try
{
return new Guid(s);
}
catch (FormatException)
{
return null;
}
}
}
#else
#error switch parsing to .NET 4.0
#endif
И поместите свою строку в свой *.csproj
<DefineConstants Condition=" '$(TargetFrameworkVersion)' != 'v4.0' ">NOT_RUNNING_ON_4</DefineConstants>