Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect the C# version at compile time

Tags:

c#

Is it possible to detect if the current version of C# is 6 or above with a preprocessor directive, so at compile time?

I want to do something like this:

var myVar = ...;
string name;

#if VERSION_6_OR_MORE
    name = nameof(myVar);
#else
    name = "myVar";
#endif

I use Visual Studio 2015 and C# 6, so I can use nameof(). Someone else wanting to compile this code however may be using an older version, where nameof() isn't present.

I want to use a preprocessor directive so I can keep the nameof() in C# 6, but someone else who doesn't use that version can compile it as well.

like image 684
A.Pissicat Avatar asked Oct 11 '16 09:10

A.Pissicat


3 Answers

The nameof() operator is meant to reduce maintenance: using it you don't have identifiers hidden in strings, so when you rename a variable, parameter or member, the place where you use it (for example an ArgumentNullException(nameof(paramName))) will be updated when you refactor the paramName name.

Now using your approach, you're effectively doubling your maintenance surface instead of reducing it (as you now have both the string variant and the nameof() version, both of which having to be maintained), negating the use of nameof() altogether.

So if you want to support older C# versions, stick to features that work in those versions: use identifiers in strings instead.

like image 85
CodeCaster Avatar answered Nov 15 '22 20:11

CodeCaster


You can explicitly specify language version and define conditional constant in your project file:

<LangVersion>6</LangVersion>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DefineConstants Condition="'$(LangVersion)' == '6'">DEBUG;TRACE;LANG_VERSION_6</DefineConstants>
like image 38
Vsevolod Okhrin Avatar answered Nov 15 '22 21:11

Vsevolod Okhrin


I am not aware of a pre-existing directive. But, here's what you can do:

  1. Define two build configurations: Say CSharp6 and CSharp5 (in the configuration manager).
  2. Select C6 from the configuration manger, and then go to the project properties. And define a symbol say CSHARP6.
  3. Change configurations and go to CSharp5
  4. Open project properties again and define a new symbol: CSHARP5

Then your directive conditional would look like:

#if CSHARP6
    name = nameof(myVar);
#else
    name = "myVar";
#endif

Delegate the selection of the configuration profile to the building agent, or as part of an instruction manual for compilation of the project.

like image 23
Candide Avatar answered Nov 15 '22 20:11

Candide