How to set .NET Core in #if statement for compilation
I created a multi-targeted framework project. I use something like this:
#if NET40
Console.WriteLine("Hello from .NET Core 4");
#endif
But I can't find a wildcard for .NET Core. I tried:
#if NETCOREAPP1.0
Console.WriteLine("Hello from .NET Core");
#endif
But it is not valid statement.
You need an underscore, _
, instead of a point:
NETCOREAPP1_0
or the more recent NETCOREAPP1_1
and NETCOREAPP2_0
The documentation for Target frameworks in SDK-style projects includes a list for the different preprocessor symbols.
.NET Framework
NETFRAMEWORK, NET48, NET472, NET471, NET47, NET462, NET461, NET46, NET452, NET451, NET45, NET40, NET35, NET20
.NET Standard
NETSTANDARD, NETSTANDARD2_1, NETSTANDARD2_0, NETSTANDARD1_6, NETSTANDARD1_5, NETSTANDARD1_4, NETSTANDARD1_3, NETSTANDARD1_2, NETSTANDARD1_1, NETSTANDARD1_0
.NET 5+ and .NET Core
NET, NET6_0, NET6_0_ANDROID, NET6_0_IOS, NET6_0_MACOS, NET6_0_MACCATALYST, NET6_0_TVOS, NET6_0_WINDOWS, NET5_0, NETCOREAPP, NETCOREAPP3_1, NETCOREAPP3_0, NETCOREAPP2_2, NETCOREAPP2_1, NETCOREAPP2_0, NETCOREAPP1_1, NETCOREAPP1_0
Mono
For Mono you can usually use the NetFramework monikers known by your version of Mono. For instance, Mono 6.12 includes all NetFramework versions from 2.0 to 4.8. But if you must recognise Mono per se, then MONO
and __MonoCS__
should both be defined.
Extension of Devon's answer for Visual Studio 2017 .csproj files:
Looking at the table here, you can easily define constants by using regular expressions. So you don't need to think about updating the conditions if target frameworks are added/changed.
<PropertyGroup Condition="$([System.Text.RegularExpressions.Regex]::IsMatch('$(TargetFramework)', '^net\d'))">
<DefineConstants>NETFRAMEWORK</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="$([System.Text.RegularExpressions.Regex]::IsMatch('$(TargetFramework)', '^netstandard\d'))">
<DefineConstants>NETSTANDARD</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="$([System.Text.RegularExpressions.Regex]::IsMatch('$(TargetFramework)', '^netcoreapp\d'))">
<DefineConstants>NETCORE</DefineConstants>
</PropertyGroup>
Usage:
#if NETFRAMEWORK
FrameworkSpecific();
#endif
#if NETSTANDARD
StandardSpecific();
#endif
#if NETCORE
CoreSpecific();
#endif
You can define any custom conditional compilation symbols in the following way (project.json):
"frameworks": {
"net40": {
"buildOptions": {
"define": ["NET_40"]
}
},
"netstandard1.5": {
"buildOptions": {
"define": [ "NET_STANDARD" ]
}
}
}
This approach seems to be more practical because you may use the same conditional symbol for several targets, without need to write something like
#if NET20 && NET 40 && NET45
For the new Visual Studio 2017 .csproj project system, you can find the full list of available symbols in Developing Libraries with Cross Platform Tools, How to Multitarget.
You can create composite constant(s) for it in your .csproj file like so:
<PropertyGroup Condition="'$(TargetFramework)' == 'net451' Or '$(TargetFramework)' == 'net461' ">
<DefineConstants>FULLFRAMEWORK;FULL</DefineConstants>
</PropertyGroup>
Then you can use it in a #if
compiler directive like so:
#if FULLFRAMEWORK
private bool DoSomethingFullFrameworkSpecific()
{
var connectionStringSetting = ConfigurationManager.ConnectionStrings[connectionStringName];
return connectionStringSetting != null;
}
#endif
While Vitaliy Fedorchenko's answer is correct, it should be noted that there is a bug in the .NET Core xproj project type. When you define a conditional compilation symbol through the project settings, it defines the element as "defines", but this is incorrect. It should create an element called "define". You can work around the issue by editing the project.json file manually.
I have logged this bug with Microsoft in two places. Please take the time to register your annoyance with Microsoft so that they eventually get around to fixing it and not causing this grief for others.
This thread has a detailed explanation of the problem with steps to reproduce, and screenshots:
3 Issues with NET Core Visual Studio Projects #4022
This is the Microsoft Connect bug report:
https://connect.microsoft.com/VisualStudio/feedbackdetail/view/2983351/conditional-compilation-symbols-broken-in-net-core-projects#tabs