言語バージョンを更新したらビルドできない!
VS2019で作成したソリューションのプロジェクトはデフォルトで以下の設定になります。
- ターゲットフレームワーク:
net5.0 - 言語:C# 9.0(
latest)
VS2019で作成したソリューションとプロジェクトは、.slnファイルや.csprojファイルの中身の構造がVS2022では変更されませんでしたのでVS2022でそのまま開くことが可能です。
しかし、この状態でうきうきでC#10.0のglobal usingやfile scoped namespaceに書き換えを行っても、「{が必要です」といった基本的な文法エラーで殴られてビルドが通らないことがあります。アイエエエ!?CS1513!?CS1513ナンデ!?
(以下、うきうきで変更したら怒られたときの画面)

上図をよく見たらわかるのですが、実はVS2022のエディタはエラーだと思っていない(問題は見つかりませんでしたとか言ってる)のにビルド時にエラーになってます。
ついでにCS8032で「アナライザー System.Text.Json.SourceGeneration.JsonSourceGenerator のインスタンスは C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\analyzers\dotnet\cs\System.Text.Json.SourceGeneration.dll (ファイルまたはアセンブリ 'Microsoft.CodeAnalysis, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'、またはその依存関係の 1 つが読み込めませんでした。指定されたファイルが見つかりません。) から作成できません。」とか言われて警告ビンタされます。
本稿ではこれの原因と対処法について説明します。
原因はSourceGeneratorとかに使うMicrosoft.Net.Compilers.Toolset
結論からいうとMicrosoft.Net.Compilers.Toolsetを参照しているプロジェクトはこのライブラリのバージョンを更新しないとビルドが通りません。
こいつの説明に答えが書いてあります。
.NET Compilers Toolset Package.
Referencing this package will cause the project to be built using the C# and Visual Basic compilers contained in the package, as opposed to the version installed with MSBuild.
以下、google翻訳
.NETコンパイラツールセットパッケージ。
このパッケージを参照すると、MSBuildでインストールされたバージョンではなく、パッケージに含まれているC#およびVisualBasicコンパイラを使用してプロジェクトがビルドされます。
**そんな仕様だったの!?**という感じではありますが、.csprojファイルで設定したターゲットフレームワークやLangVersionよりも優先してMicrosoft.Net.Compilers.Toolsetに内蔵されたRoslynコンパイラが動作する、というわけです。RoslynコンパイラのバージョンはMicrosoft.Net.Compilers.Toolset.dllによって決まります。このため、dllのバージョンが古いとC#10より前のコンパイラでビルドされるのでビルド時にエラーが出るというわけです。エディタのエラー検出に使うコンパイラはおそらく.csprojの設定に依存して決まるのでしょう。多分。
dllのバージョンとRoslynコンパイラのバージョンの対応
MSDNに対応表があります。2022/01/14時点では3.xまでしか表がありません(英語サイトも)が、そのうち追加されるでしょう。
| Roslyn パッケージ バージョン | サポートされている Visual Studio の最小バージョン |
|---|---|
| 3.x | Visual Studio 2019 |
| 2.10.0 | Visual Studio 2017 バージョン 15.9 |
| 2.9.0 | Visual Studio 2017 バージョン 15.8 |
| 2.8.2 | Visual Studio 2017 バージョン 15.7 |
| 2.7.0 | Visual Studio 2017 バージョン 15.6 |
| 2.6.1 | Visual Studio 2017 バージョン 15.5 |
| 2.4.0 | Visual Studio 2017 バージョン 15.4 |
| 2.3.2 | Visual Studio 2017 バージョン 15.3 |
| 2.2.0 | Visual Studio 2017 バージョン 15.2 |
| 2.1.0 | Visual Studio 2017 バージョン 15.1 |
| 2.0.0 | Visual Studio 2017 RTM |
| 1.3.2 | Visual Studio 2015 更新プログラム 3 |
| 1.2.2 | Visual Studio 2015 更新プログラム 2 |
| 1.1.1 | Visual Studio 2015 更新プログラム 1 |
| 1.0.1 | Visual Studio 2015 RTM |
私のプロジェクトでは3.11.0を使っていました。そりゃビルドが通らんわ・・・というわけでUpdate-Packageを実行すればビルドが通ったのでした。
なお、記事作成時点では最新バージョンは4.0.1になります。
あとがき
初めてC#を触ったときから「namespaceなんて99%はファイル全体で同じなのになんでインデントせにゃいかんの?」と思っていたのが、C#10.0でようやく解消できます。ずいぶん待たされましたし、file scoped namespaceが導入される理由が「HelloWorldの簡略化」みたいなとこがありますが、これが嫌だったのは私だけだったんでしょうか?
他にもC#10やNET6にはたくさんの機能追加があります。特にLINQのMaxBy,MinByは待望の機能ではないでしょうか?みなさんもぜひ最新バージョンへのアップデートを行いましょう!