1

Background I have created a Directory.Build.props in my root repo folder with the following contents:

<Project>
  <PropertyGroup>
    <LangVersion>7.3</LangVersion>
  </PropertyGroup>
</Project>

I need to prevent the usage of C# 8 syntax within our codebase, since it is targeting .Net 4.7.2 The above file sets the LangVersion property for each project within the solution.

The problem

Our codebase is big. Many projects within one single solution with many programmers working in differents and / or adding new ones, this is not a problem itself but rather the fact that any programmer can override the LangVersion within their own .csproj file.

I know we can stop those changes in the code review phase or by sending reminders every hour to all the programmers telling them not to use C# 8 for this specific project. But I was wondering if I could just celebrate their boldness by giving them a nice and handsome compiler error.

Maybe with a custom code analizer with Roslyn? Is there any way?

taquion
  • 2,667
  • 2
  • 18
  • 29
  • 1
    In the worst case you may add a custom validation build step that checks that none of the (changed?) `.props`/`.csproj` files have LangVersion > 7.3 – Eugene Podskal Nov 29 '19 at 21:58
  • Thanks @EugenePodskal, I have already thought that maybe a custom script run in the Pre-build event command line might do the trick.However I would prefer something more neat perhaps.. – taquion Nov 29 '19 at 22:33

1 Answers1

1

Try something like this:

<Project>

    <Target Name="RestrictLangVersion" BeforeTargets="Compile">
        <PropertyGroup>
            <UnsupportedTarget Condition=" '$(MaxSupportedLangVersion)' == '7.3' AND '$(LangVersion)' == '8.0' ">true</UnsupportedTarget>
        </PropertyGroup>
        <Error Text="At *YOUR_COMPANY* we discourage the use of C# 8.0 on unsupported targets" Condition=" '$(UnsupportedTarget)' == 'true' " />
    </Target>

</Project>

You can pop that in a Directory.Build.targets high up in your CI agent and it should do the trick.

You'll need to add the logic for preview etc... (as there are other values of LangVersion that will result in 8.0) and some of those will be dependant on the version of csc, so I've left out the hard part.

Basically you'll need to replicate the logic here: https://github.com/dotnet/roslyn/blob/97123b393c3a5a91cc798b329db0d7fc38634784/src/Compilers/CSharp/Portable/LanguageVersion.cs#L353-L364

bearing in mind that it will change across different versions of csc.

Stuart
  • 5,358
  • 19
  • 28
  • 1
    No worries, I am thinking about making a nuget package that does this with the extra smarts I described. As an ex-team-lead, be careful with these sorts of overbearing policies, hopefully this build warning starts some healthy discussion, rather than a hard rule. – Stuart Dec 01 '19 at 12:48
  • 1
    Just added a comment at the end regarding the missing logic. – Stuart Dec 01 '19 at 12:52
  • 1
    I am indeed one of those bold programmers that were making use of C# 8 as soon as it was supported (at least some features) for .net 4.7 in the latest Visual Studio update ☹️. So I am kind of harakiri-myself here... – taquion Dec 01 '19 at 12:55
  • 1
    I'm also guilty: https://stu.dev/csharp8-doing-unsupported-things/ – Stuart Dec 01 '19 at 12:59
  • 1
    Nice article! I loved this: "So the good news is that you can enable C# 8.0 on other targets, however it is "unsupported" i.e. this is probably not a good idea". – taquion Dec 01 '19 at 13:09