C#でコードスタイル規則のエラーをビルドエラーにする

3 min read読了の目安(約3200字

C#でvarでの変数宣言を強制したい。でも、有名どころのStyleCopAnalyzerRoslynatorには、そのようなルールがない(たくさんのルールがあるので見逃してるだけかもしれないが。)

一方、コードスタイル規則ってのがある。.editorconfigで設定を行うと、プロジェクトで共有できてVisual Studio上でもその内容が反映される。エラーを指定した設定項目に一致するコードが見つかったら赤の下線が引かれたりする。残念ながらVS Codeではうまく反映してくれなかったけど、Visual StudioとかRiderだったら反映してくれた。

.editorconfigに次のように設定すると、

[*.cs]
csharp_style_var_elsewhere = true:error
csharp_style_var_for_built_in_types = true:error
csharp_style_var_when_type_is_apparent = true:error

Visual Studioはこんな風に反応してくれる。

visual studio でのエラー表示

ただ、残念ながらこれはエディタの表示上の話で、ビルドしてもエラーなく成功してしまう。これをエラーにしたい。

どうやらできるらしい。

https://docs.microsoft.com/ja-jp/dotnet/fundamentals/code-analysis/overview#enable-on-build

手順にしたがってやっていく。

  1. MSBuildプロパティEnforceCodeStyleInBuildtrueに設定します。
  2. .editorconfigファイルで、ビルド時に実行する各 "IDE" コードスタイルルールを警告またはエラーとして構成します。
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
[*.cs]
csharp_style_var_elsewhere = true:error
csharp_style_var_for_built_in_types = true:error
csharp_style_var_when_type_is_apparent = true:error

# IDE0007: 暗黙的な型の使用
dotnet_diagnostic.IDE0007.severity = error

無事にビルドエラーになった。

ちゃんとビルドエラー

追加で試してみた

いくつか気になったので追加で試してみた。

ルールIDの設定だけでビルドエラーになるのか?

.editorconfigで、csharp_style_var_elsewhereとかオプションの指定を外して、ルールID(ここではIDE0007)の指定だけにしても、ビルドエラーになるのか?

[*.cs]
# csharp_style_var_elsewhere = true:error
# csharp_style_var_for_built_in_types = true:error
# csharp_style_var_when_type_is_apparent = true:error

# IDE0007: 暗黙的な型の使用
dotnet_diagnostic.IDE0007.severity = error

ならなかった。

オプションの指定をerror以外にしてもビルドエラーになるのか?

.editorconfigで、csharp_style_var_elsewhereとかオプションの指定をerror以外にしても、ビルドエラーになるのか?

[*.cs]
csharp_style_var_elsewhere = true:info
csharp_style_var_for_built_in_types = true:silent
csharp_style_var_when_type_is_apparent = true:none

# IDE0007: 暗黙的な型の使用
dotnet_diagnostic.IDE0007.severity = error

こまかいことは書かないが、無指定とnone以外はビルドエラーになった。でもややこしいのであわせておくのがベターだと思う。

Microsoft.CodeAnalysis.CSharp.CodeStyleを直接参照してもビルドエラーにできるか?

どうやら、EnforceCodeStyleInBuildtrueにすると、Microsoft.CodeAnalysis.CSharp.CodeStyleが参照され、そいつがビルドエラーにしている模様。なので、EnforceCodeStyleInBuildを指定せずにNuGetからMicrosoft.CodeAnalysis.CSharp.CodeStyleを直接参照するとどうなるのか。

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netstandard2.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <None Include="..\.editorconfig" Link=".editorconfig" />
  </ItemGroup>

  <ItemGroup>
     <PackageReference Include="Microsoft.CodeAnalysis.CSharp.CodeStyle" Version="3.9.0">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
  </ItemGroup>

</Project>

ちゃんとビルドエラーになった。でもドキュメントにはEnforceCodeStyleInBuildtrueにしろってなってるので、そっちに従っておいたほうが、今後を考えてもベターなような気はする。