如果在解决方案文件中的任何项目中设置了某些 MsBuild 属性,是否有办法引发自定义编译错误?

Is there a way to throw a custom compilation error if some MsBuild property is set in any project within a solution file?

背景 我在我的根回购文件夹中创建了一个 Directory.Build.props,内容如下:

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

我需要防止在我们的代码库中使用 C# 8 语法,因为它针对的是 .Net 4.7.2 上述文件为解决方案中的每个项目设置 LangVersion 属性。

问题

我们的代码库很大。许多项目在一个单一的解决方案中,许多程序员在不同的工作和/或添加新的解决方案,这本身不是问题,而是任何程序员都可以在他们自己的 .csproj 文件中覆盖 LangVersion 的事实。

我知道我们可以在代码审查阶段停止这些更改,或者每小时向所有程序员发送提醒,告诉他们不要在这个特定项目中使用 C# 8。但我想知道我是否可以通过给他们一个漂亮而漂亮的编译器错误来庆祝他们的大胆。

也许使用 Roslyn 的自定义代码分析器?有什么办法吗?

尝试这样的事情:

<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>

您可以在 CI 代理的 Directory.Build.targets 高处弹出它,它应该可以解决问题。

您需要为 preview 等添加逻辑...(因为 LangVersion 的其他值会导致 8.0),其中一些会取决于 csc 的版本,所以我省略了困难的部分。

基本上您需要在此处复制逻辑: https://github.com/dotnet/roslyn/blob/97123b393c3a5a91cc798b329db0d7fc38634784/src/Compilers/CSharp/Portable/LanguageVersion.cs#L353-L364

请注意,它会在 csc 的不同版本中发生变化。