C#のバージョン一覧と確認・変更方法|プロジェクトで使える機能の違いまで解説
はじめに
C#で開発していると、「この機能はC# 10以降で使用できます」「C# バージョンを上げたい」「.NETのバージョンを上げたのに新しい構文が使えない」といった場面があります。C#のバージョンは、単に言語の新旧を表すだけでなく、使える構文、プロジェクトのターゲットフレームワーク、Visual Studioや.NET SDKのバージョンと深く関係しています。
特に近年のC#は、record、init、Nullable参照型、global using、requiredメンバー、プライマリコンストラクター、コレクション式、拡張メンバーなど、生産性や安全性を高める機能が継続的に追加されています。一方で、最新のC# バージョンを指定すれば常に正解というわけではありません。チーム開発、CI/CD、既存ライブラリ、.NET Frameworkとの互換性を考える必要があります。
この記事では、C#のバージョン一覧、.NETとの対応関係、確認方法、変更方法、実務での選び方、よくあるエラーまでまとめて解説します。
1. C#のバージョンとは?まず押さえるべき基礎知識
1-1. C#のバージョンは「言語バージョン」を指す
「C# バージョン」とは、基本的にC#言語そのもののバージョン、つまり「どの構文や言語機能をコンパイラが受け付けるか」を表します。
たとえば、次のような違いがあります。
C#// C# 9.0以降で使えるrecord
public record User(string Name, int Age);
// C# 10以降で使えるglobal using
global using System.Text;
// C# 11以降で使えるrequired
public class Product
{
public required string Name { get; init; }
}
// C# 12以降で使えるプライマリコンストラクター
public class Person(string name)
{
public string Name { get; } = name;
}
同じC#コードでも、プロジェクトのC# バージョンが古いとビルドエラーになります。つまりC#のバージョンは、「どの書き方が使えるか」を決める重要な設定です。
1-2. C#・.NET・Visual Studio・SDKのバージョンの違い
C# バージョンを理解するには、C#、.NET、Visual Studio、.NET SDKの違いを分けて考える必要があります。
| 種類 | 役割 | 例 |
|---|---|---|
| C# | プログラミング言語 | C# 10、C# 12、C# 14 |
| .NET | 実行基盤・ライブラリ・フレームワーク | .NET 6、.NET 8、.NET 10 |
| .NET SDK | ビルドやコンパイルに使う開発キット | 8.0.xxx、10.0.xxx |
| Visual Studio | IDE、開発環境 | Visual Studio 2022、Visual Studio 2026 |
| TargetFramework | プロジェクトが対象にする.NET | net8.0、net10.0、net48 |
C#は言語、.NETはアプリを動かす基盤、SDKはビルドするための道具、Visual Studioは開発環境です。C# バージョンは単独で決まるのではなく、通常はプロジェクトのTargetFrameworkに応じて既定値が選ばれます。Microsoftのドキュメントでも、最新のC#コンパイラはプロジェクトのターゲットフレームワークに基づいて既定の言語バージョンを決定すると説明されています。
1-3. C#のバージョンが変わると何が変わるのか
C# バージョンが変わると、主に次のものが変わります。
1つ目は、使える構文です。たとえば、C# 8.0ではNullable参照型、C# 9.0ではrecord、C# 10ではglobal using、C# 11ではrequired、C# 12ではプライマリコンストラクターが使えるようになりました。
2つ目は、コードの書きやすさです。新しいC# バージョンでは、同じ処理をより短く、安全に、読みやすく書ける機能が増えています。
3つ目は、ライブラリやランタイムとの関係です。一部の言語機能はコンパイラだけで完結せず、.NET側の型やランタイム機能を必要とします。MicrosoftのC#履歴ドキュメントでも、C#の一部機能は標準ライブラリの型やメソッドに依存すると説明されています。
1-4. 最新バージョンを使えばよいとは限らない理由
新規開発なら最新の安定版を選ぶ場面が多いですが、常に最新のC# バージョンを指定すればよいわけではありません。
理由は、開発者のPC、CI/CD環境、ビルドサーバー、Visual Studio、.NET SDKのバージョンがそろっていないと、環境によってビルド結果が変わる可能性があるからです。また、古い.NET Frameworkプロジェクトでは、新しいC#構文を使えるように見えても、必要なランタイム機能やライブラリが不足する場合があります。
特に<LangVersion>latest</LangVersion>は注意が必要です。Microsoftは、latestを指定するとマシンごとに使われるコンパイラの最新バージョンが変わり、ビルドの信頼性が低下する可能性があるため、設定しないよう警告しています。
2. C#のバージョン一覧と対応する.NET
2-1. C# 1.0〜最新バージョンまでの一覧表
C#の主なバージョンを一覧にすると、次のようになります。
| C# バージョン | リリース時期の目安 | 主な機能 |
|---|---|---|
| C# 1.0 | 2002年 | クラス、構造体、インターフェイス、プロパティ、イベント、デリゲート |
| C# 1.2 | 2003年 | foreachに関する改善など |
| C# 2.0 | 2005年 | ジェネリック、Nullable値型、匿名メソッド、イテレーター、partial型 |
| C# 3.0 | 2007年 | LINQ、ラムダ式、拡張メソッド、匿名型、暗黙的型付け、オブジェクト初期化子 |
| C# 4.0 | 2010年 | dynamic、名前付き引数、オプション引数、ジェネリックの共変性・反変性 |
| C# 5.0 | 2012年 | async / await、呼び出し元情報属性 |
| C# 6.0 | 2015年 | 文字列補間、null条件演算子、nameof、式形式メンバー、例外フィルター |
| C# 7.0 | 2017年 | タプル、分解、パターンマッチング、ローカル関数、out var |
| C# 7.1 | 2017年 | async Main、defaultリテラル、推論されるタプル要素名 |
| C# 7.2 | 2017年 | readonly struct、in引数、ref struct、private protected |
| C# 7.3 | 2018年 | タプル比較、ジェネリック制約の拡張、stackalloc改善 |
| C# 8.0 | 2019年 | Nullable参照型、switch式、非同期ストリーム、インデックスと範囲、既定インターフェイスメンバー |
| C# 9.0 | 2020年 | record、init、トップレベルステートメント、パターンマッチング強化 |
| C# 10 | 2021年 | global using、ファイルスコープ名前空間、record struct、拡張プロパティパターン |
| C# 11 | 2022年 | requiredメンバー、生文字列リテラル、リストパターン、ジェネリック演算 |
| C# 12 | 2023年 | プライマリコンストラクター、コレクション式、任意型のusingエイリアス |
| C# 13 | 2024年 | paramsコレクション、新しいlock、partialプロパティ、ref struct関連の強化 |
| C# 14 | 2025年 | 拡張メンバー、null条件代入、field-backed properties、Span関連の変換強化 |
| C# 15 | プレビュー | union types、collection expression argumentsなど |
C# 14は2025年11月にリリースされ、拡張メンバー、null条件代入、nameofの強化、field-backed propertiesなどが追加されています。C# 15は2026年時点では最新のプレビューリリースとして案内されており、.NET 11 preview SDKで試せる機能としてunion typesなどが紹介されています。
2-2. C#バージョンごとの対応.NET・Visual Studioの目安
現在の.NETでは、C# バージョンの既定値はターゲットフレームワークによって決まります。
| TargetFramework | 既定のC# バージョン |
|---|---|
| .NET Framework | C# 7.3 |
| .NET Standard 2.0 | C# 7.3 |
| .NET Standard 2.1 | C# 8.0 |
| .NET Core 2.x | C# 7.3 |
| .NET Core 3.x | C# 8.0 |
| .NET 5 | C# 9.0 |
| .NET 6 | C# 10 |
| .NET 7 | C# 11 |
| .NET 8 | C# 12 |
| .NET 9 | C# 13 |
| .NET 10 | C# 14 |
| .NET 11 preview | C# 15 preview |
Microsoftの言語バージョン管理ドキュメントでは、.NET 10の既定がC# 14、.NET 11.xの既定がC# 15、.NET Frameworkの既定がC# 7.3とされています。
2-3. 各バージョンで追加された代表的な機能
C#の歴史を大きく見ると、次のように進化しています。
C# 2.0ではジェネリックが追加され、List<string>やDictionary<string, int>のような型安全なコレクションを扱いやすくなりました。
C# 3.0ではLINQが追加され、コレクションやデータソースに対して宣言的なクエリを書けるようになりました。
C# 5.0ではasync / awaitが追加され、非同期処理を同期処理に近い読みやすさで書けるようになりました。
C# 8.0ではNullable参照型が追加され、nullによる実行時エラーをコンパイル時に検出しやすくなりました。
C# 9.0ではrecordとinitが追加され、値のように扱うデータ型を簡潔に定義しやすくなりました。
C# 10以降では、global using、ファイルスコープ名前空間、requiredメンバー、プライマリコンストラクター、コレクション式など、記述量を減らしながら意図を明確にする機能が増えています。
2-4. 現在のプロジェクトで使えるC#バージョンの考え方
現在のプロジェクトで使えるC# バージョンを判断するには、まずTargetFrameworkを確認します。
XML<TargetFramework>net8.0</TargetFramework>
この場合、既定のC# バージョンはC# 12です。
XML<TargetFramework>net10.0</TargetFramework>
この場合、既定のC# バージョンはC# 14です。
明示的にLangVersionを指定していない場合、基本的にはターゲットフレームワークに対応したC# バージョンが使われます。そのため、C# バージョンを変えたい場合は、まず.NETのターゲットを変えるべきか、LangVersionだけを指定すべきかを検討します。
3. C#バージョン別の主な機能の違い
3-1. C# 2.0〜5.0:ジェネリック・LINQ・async/awaitなどの基礎機能
C# 2.0〜5.0は、現在のC#開発でも基礎となる機能がそろった時期です。
C# 2.0の代表機能はジェネリックです。ジェネリックにより、型安全なコレクションや共通処理を作れるようになりました。
C#List<string> names = new List<string>();
names.Add("Alice");
C# 3.0ではLINQが登場しました。
C#var adults = users
.Where(u => u.Age >= 20)
.OrderBy(u => u.Name)
.ToList();
C# 5.0ではasync / awaitが追加されました。
C#public async Task<string> GetTextAsync(HttpClient client)
{
return await client.GetStringAsync("https://example.com");
}
この時期の機能は、現在のC#でもほぼ必須知識です。初心者がC#を学ぶ場合も、ジェネリック、LINQ、非同期処理は早い段階で理解しておきたい機能です。
3-2. C# 6.0〜8.0:null条件演算子・タプル・Nullable参照型
C# 6.0〜8.0では、コードの安全性と読みやすさを高める機能が増えました。
C# 6.0ではnull条件演算子が使えるようになりました。
C#var length = user?.Name?.Length;
C# 7.0ではタプルと分解が追加されました。
C#(string name, int age) user = ("Alice", 30);
Console.WriteLine(user.name);
var (name, age) = user;
C# 8.0ではNullable参照型が追加されました。
C##nullable enable
string name = "Alice";
string? nickname = null;
Nullable参照型を有効にすると、nullになり得る参照型をstring?のように明示できるため、NullReferenceExceptionの予防に役立ちます。
3-3. C# 9.0〜11:record・init・global using・required
C# 9.0〜11では、データ中心の設計や簡潔な記述を支える機能が強化されました。
C# 9.0のrecordは、値の等価性を持つデータ型を簡潔に定義できます。
C#public record User(string Name, int Age);
initを使うと、初期化時だけ代入できるプロパティを作れます。
C#public class User
{
public string Name { get; init; } = "";
}
C# 10のglobal usingは、プロジェクト全体で使う名前空間をまとめて定義できます。
C#global using System.Text;
global using System.Text.Json;
C# 11のrequiredメンバーは、オブジェクト作成時に必ず指定すべきプロパティを表現できます。
C#public class Product
{
public required string Name { get; init; }
}
これらの機能は、Web API、DTO、設定クラス、ドメインモデルなどで特に役立ちます。
3-4. C# 12〜最新:プライマリコンストラクターなどの新機能
C# 12では、プライマリコンストラクターとコレクション式が大きなポイントです。
C#public class Customer(string name)
{
public string Name { get; } = name;
}
コレクション式を使うと、配列やリストを簡潔に初期化できます。
C#int[] numbers = [1, 2, 3, 4, 5];
C# 13では、paramsで配列以外のコレクションを扱いやすくなるなど、既存機能の表現力が高まりました。
C# 14では、拡張メンバー、null条件代入、field-backed propertiesなどが追加されています。たとえば、null条件代入により、対象がnullでない場合だけ代入するような処理を簡潔に書けます。
C# 15はプレビュー段階で、collection expression argumentsやunion typesなどが紹介されています。プレビュー機能は実務導入前に仕様変更の可能性を考慮する必要があります。
3-5. 実務で特に影響が大きい機能の比較
実務で影響が大きいC# バージョンの機能を比較すると、次のようになります。
| 機能 | C# バージョン | 実務での影響 |
|---|---|---|
| ジェネリック | 2.0 | 型安全なコレクション・共通処理の基礎 |
| LINQ | 3.0 | データ加工・検索処理が読みやすくなる |
| async/await | 5.0 | 非同期I/O、Web API、DBアクセスで重要 |
| null条件演算子 | 6.0 | nullチェックの記述量を削減 |
| タプル | 7.0 | 複数値の返却が簡潔になる |
| Nullable参照型 | 8.0 | null安全性の向上 |
| record | 9.0 | DTO・値オブジェクトの定義が簡潔になる |
| global using | 10 | usingの重複を削減 |
| required | 11 | 初期化漏れを防ぎやすい |
| プライマリコンストラクター | 12 | クラス定義を簡潔にできる |
| 拡張メンバー | 14 | 拡張メソッド以外の拡張表現が強化される |
特に、Nullable参照型、record、requiredは、保守性やバグ予防に直結しやすい機能です。
4. 自分のC#バージョンを確認する方法
4-1. .NET SDKのバージョンを確認する方法
まず、インストールされている.NET SDKを確認します。
Bashdotnet --version
複数のSDKを確認する場合は、次のコマンドを使います。
Bashdotnet --list-sdks
詳細情報を確認するには、次のコマンドが便利です。
Bashdotnet --info
ただし、ここで表示されるのは.NET SDKのバージョンであり、プロジェクトで実際に使われているC# バージョンそのものではありません。C# バージョンは、SDK、TargetFramework、LangVersionの組み合わせで決まります。
4-2. プロジェクトで使われているC#バージョンを確認する方法
プロジェクトで実際に使われているC# バージョンを確認するには、次の方法があります。
最も確実なのは、コードに一時的に次の行を追加してビルドする方法です。
C##error version
この行を入れてビルドすると、コンパイラのバージョンと現在選択されているC#言語バージョンを含むエラーが表示されます。Microsoftのドキュメントでも、現在使用している言語バージョンを確認する方法として#error versionが紹介されています。
確認後は、必ずこの行を削除してください。
4-3. csprojファイルのLangVersionを確認する
プロジェクトの.csprojファイルにLangVersionが書かれている場合、その指定がC# バージョンに影響します。
XML<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<LangVersion>12.0</LangVersion>
</PropertyGroup>
LangVersionが書かれていない場合は、通常、TargetFrameworkに応じた既定のC# バージョンが使われます。
たとえば、次のようにLangVersionがない場合、
XML<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
net8.0に対応する既定のC# バージョン、つまりC# 12が使われます。
4-4. Visual Studioで確認する方法
Visual Studioでは、プロジェクトのプロパティから言語バージョンを確認できます。
プロジェクトを右クリックし、プロパティを開き、ビルド関連の詳細設定を確認します。Microsoftのドキュメントでは、Visual Studioのプロジェクトプロパティページのビルドタブ配下にある詳細設定ページで、選択されている言語バージョンを確認できると説明されています。
ただし、現在のVisual Studioでは、C#言語バージョンの既定値がTargetFrameworkに合わせて調整されるため、UIから直接変更するオプションは基本的に無効です。変更したい場合は、ターゲットフレームワークを変えるか、.csprojを編集します。
4-5. コードで使える機能からバージョンを判断する方法
簡易的には、特定の構文が使えるかどうかでC# バージョンを推測できます。
たとえば、次のコードが使えるならC# 9.0以降です。
C#public record User(string Name);
次のコードが使えるならC# 10以降です。
C#global using System;
次のコードが使えるならC# 11以降です。
C#public class User
{
public required string Name { get; init; }
}
次のコードが使えるならC# 12以降です。
C#public class User(string name)
{
public string Name { get; } = name;
}
ただし、この方法はあくまで目安です。正確に確認するには、#error versionや.csprojの設定を確認しましょう。
5. C#のバージョンを変更・指定する方法
5-1. csprojでLangVersionを指定する
C# バージョンを明示的に指定するには、.csprojにLangVersionを追加します。
XML<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<LangVersion>12.0</LangVersion>
</PropertyGroup>
C# 14を指定する場合は、次のように書きます。
XML<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<LangVersion>14.0</LangVersion>
</PropertyGroup>
プレビュー機能を使いたい場合は、次のように指定します。
XML<PropertyGroup>
<LangVersion>preview</LangVersion>
</PropertyGroup>
Microsoftのドキュメントでも、C# バージョンを明示的に指定する方法として、プロジェクトファイル内に<LangVersion>を追加する方法が示されています。
5-2. latest・preview・defaultの違い
LangVersionには、数値以外にもいくつかの指定方法があります。
| 指定値 | 意味 |
|---|---|
12.0、14.0など | 指定したC# バージョンまでの構文を使う |
preview | コンパイラが対応する最新プレビュー構文を使う |
latest | インストール済みコンパイラの最新リリース版を使う |
latestMajor | 最新のメジャーリリース版を使う |
default | コンパイラの既定の言語バージョンを使う |
注意点として、LangVersionを省略することと、<LangVersion>default</LangVersion>を書くことは同じではありません。LangVersionを省略した場合はTargetFrameworkに対応する既定のC# バージョンが使われますが、default指定はコンパイラ側の既定に従います。Microsoftのドキュメントでも、この違いが説明されています。
実務では、基本的にLangVersionは省略し、TargetFrameworkに任せるのがおすすめです。明示する場合は、latestよりも12.0や14.0のように固定したほうが、環境差を防ぎやすくなります。
5-3. Directory.Build.propsで複数プロジェクトに一括指定する
ソリューション内に複数のプロジェクトがある場合、各.csprojに同じLangVersionを書くのは手間です。この場合は、ソリューションルートなどにDirectory.Build.propsを作成します。
XML<Project>
<PropertyGroup>
<LangVersion>14.0</LangVersion>
</PropertyGroup>
</Project>
このファイルを置いたディレクトリ配下のプロジェクトに設定が適用されます。Microsoftのドキュメントでも、複数プロジェクトに言語バージョンを設定する方法としてDirectory.Build.propsが紹介されています。
ただし、C#とVisual Basicのプロジェクトが混在している場合は注意が必要です。言語ごとにバージョンの考え方が異なるため、共通設定が意図しない影響を与えることがあります。
5-4. Visual Studioから言語バージョンを変更する方法
現在のVisual Studioでは、C# バージョンはTargetFrameworkに合わせて決まるため、UIから直接C# バージョンだけを変更する方法は基本的に推奨されません。Microsoftのドキュメントでも、Visual StudioではUIを使って言語バージョンを変更するオプションは無効になり、変更するにはターゲットフレームワークを変更すると説明されています。
Visual Studioで変更したい場合は、次の流れになります。
まず、プロジェクトのプロパティを開きます。次に、対象フレームワークを.NET 8から.NET 10のように変更します。TargetFrameworkが変わると、それに応じて既定のC# バージョンも変わります。
C# バージョンだけを明示的に変えたい場合は、Visual Studio上で.csprojを編集し、LangVersionを追加します。
5-5. バージョン指定後にビルドエラーが出る場合の確認ポイント
LangVersionを指定したあとにビルドエラーが出る場合は、次の点を確認してください。
まず、インストールされている.NET SDKが指定したC# バージョンに対応しているか確認します。
Bashdotnet --list-sdks
次に、TargetFrameworkが指定したC# バージョンと対応しているか確認します。たとえば、net6.0のままC# 14を指定するような構成はサポート対象外になる可能性があります。
また、CI/CD環境で古いSDKが使われていないかも確認します。ローカルではビルドできるのにCIで失敗する場合、多くはSDKのバージョン差が原因です。
6. C#バージョンと.NETバージョンの対応関係
6-1. C#の既定バージョンはターゲットフレームワークで決まる
現在のC#では、既定の言語バージョンはターゲットフレームワークで決まります。
XML<TargetFramework>net8.0</TargetFramework>
この場合はC# 12が既定です。
XML<TargetFramework>net10.0</TargetFramework>
この場合はC# 14が既定です。
この仕組みにより、ターゲットフレームワークで使えないランタイム機能を必要とするC#構文を誤って使うリスクを下げられます。
6-2. .NET Frameworkで使えるC#バージョンの注意点
.NET Frameworkプロジェクトでは、既定のC# バージョンはC# 7.3です。Microsoftの対応表でも、.NET FrameworkはすべてC# 7.3が既定とされています。
古い.NET Frameworkプロジェクトで新しいC#構文を使いたい場合、LangVersionを変更すれば一部のコンパイラ機能は使えることがあります。しかし、すべての機能が安全に使えるとは限りません。
特に、ランタイムや標準ライブラリの型に依存する機能では問題が起きることがあります。そのため、.NET Frameworkのまま無理に最新C# バージョンを使うより、可能であれば.NET 8や.NET 10などの現行.NETへ移行するほうが長期的には安全です。
6-3. .NET Core・.NET 5以降での考え方
.NET Core 3.x以降、C# バージョンと.NETの関係はかなり明確になりました。
.NET Core 3.xはC# 8.0、.NET 5はC# 9.0、.NET 6はC# 10、.NET 7はC# 11、.NET 8はC# 12、.NET 9はC# 13、.NET 10はC# 14という形で対応します。
新規開発では、サポート期間と安定性を考え、LTS版の.NETを選ぶのが一般的です。.NET 10は2025年11月にリリースされたLTSで、2028年11月までサポートされるとMicrosoftが発表しています。
6-4. 古い.NETで新しいC#機能を使うときの制限
古い.NETで新しいC#機能を使うと、次のような制限があります。
コンパイラだけで完結する構文であれば使える可能性があります。しかし、ランタイム機能、BCLの型、属性、ライブラリのアノテーションなどが必要な機能では、実行時エラーや互換性の問題が発生することがあります。
たとえば、Nullable参照型はコンパイラの解析が中心ですが、ライブラリ側がNullableアノテーションに対応しているほうが効果を発揮します。C# 8.0の説明でも、Nullable参照型はコンパイラ実装の機能である一方、ライブラリにnull状態の注釈が加わることでより有用になると説明されています。
6-5. TargetFrameworkとLangVersionの関係
TargetFrameworkは、アプリが対象にする.NETを指定します。
XML<TargetFramework>net8.0</TargetFramework>
LangVersionは、C#言語バージョンを指定します。
XML<LangVersion>12.0</LangVersion>
基本的には、TargetFrameworkに合わせてC# バージョンを選ぶのが安全です。たとえば、net8.0ならC# 12、net10.0ならC# 14を使います。
Microsoftのドキュメントでは、ターゲットTFMに関連付けられているバージョンより新しいC#言語バージョンの使用はサポートされていないと説明されています。
7. プロジェクトで使うC#バージョンの選び方
7-1. 新規開発ではどのバージョンを選ぶべきか
新規開発では、基本的に利用する.NETのLTS版に対応するC# バージョンを選ぶのがおすすめです。
たとえば、.NET 8を採用するならC# 12、.NET 10を採用するならC# 14が自然です。LangVersionを明示的に指定せず、TargetFrameworkに任せる構成にしておくと、互換性の問題を避けやすくなります。
XML<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
</PropertyGroup>
このように書けば、.NET 10に対応する既定のC# バージョンが使われます。
7-2. 既存プロジェクトでは無理に最新化すべきか
既存プロジェクトでは、無理に最新C# バージョンへ上げる必要はありません。
特に、長年運用している.NET Frameworkプロジェクト、外部ライブラリが多いプロジェクト、CI/CD環境が古いプロジェクトでは、C# バージョンだけを先に上げるとトラブルの原因になります。
おすすめの進め方は、まず.NET SDKとVisual Studioを更新し、次にTargetFrameworkを上げ、最後にC#の新機能を段階的に導入する流れです。構文だけを先に新しくするより、プロジェクト全体の実行基盤を整えるほうが安全です。
7-3. チーム開発でバージョンを統一する重要性
チーム開発では、C# バージョンを統一することが非常に重要です。
ある開発者のPCではC# 14が使えるのに、別の開発者のPCではC# 12までしか使えない場合、ビルドエラーやIDEの解析エラーが発生します。
対策として、次の設定をそろえます。
JSON{
"sdk": {
"version": "10.0.100",
"rollForward": "latestFeature"
}
}
global.jsonでSDKバージョンを固定すれば、ローカルとCI/CDで使うSDKをそろえやすくなります。さらに、必要に応じてDirectory.Build.propsでLangVersionを統一します。
7-4. ライブラリ開発で注意すべき互換性
ライブラリ開発では、利用者がどの.NET環境を使うかを考える必要があります。
アプリケーション開発であれば、自分たちの環境だけを考えればよい場面が多いですが、ライブラリは利用者のTargetFrameworkに合わせる必要があります。
たとえば、netstandard2.0対応ライブラリでは、既定のC# バージョンはC# 7.3です。新しいC#構文を使う場合は、利用者の環境やビルド条件に影響がないか確認しましょう。
ライブラリでは、言語機能よりも公開APIの互換性、ターゲットフレームワーク、NuGetパッケージの依存関係が重要になることがあります。
7-5. preview版を使うメリット・デメリット
LangVersionにpreviewを指定すると、最新のプレビュー機能を試せます。
XML<PropertyGroup>
<LangVersion>preview</LangVersion>
</PropertyGroup>
メリットは、新しい言語機能を早期に検証できることです。フレームワーク開発、技術検証、社内ツール、学習用途では有効です。
デメリットは、仕様変更やビルド環境差のリスクがあることです。プレビュー機能は将来の正式版で構文や挙動が変わる可能性があります。本番運用の業務システムでは、原則として安定版のC# バージョンを使うほうが安全です。
8. C#バージョン関連でよくあるエラーと対処法
8-1. 「この機能はC#○以降で使用できます」と表示される
このエラーは、現在のプロジェクトのC# バージョンが、使おうとしている構文に対応していないときに表示されます。
たとえば、C# 8.0以下でrecordを使うとエラーになります。
対処法は次の通りです。
まず、TargetFrameworkを確認します。
XML<TargetFramework>net5.0</TargetFramework>
recordを使うならC# 9.0以降が必要です。net5.0以降を使うか、適切なLangVersionを指定します。
XML<LangVersion>9.0</LangVersion>
ただし、TargetFrameworkより新しいC# バージョンを無理に指定するのは避けましょう。
8-2. Visual Studioでは動くのにCI/CDでビルドできない
Visual Studioではビルドできるのに、GitHub Actions、Azure Pipelines、JenkinsなどのCI/CDでビルドできない場合は、CI側の.NET SDKが古い可能性があります。
確認コマンドは次の通りです。
Bashdotnet --info
dotnet --list-sdks
CIの設定で使う.NET SDKを明示しましょう。たとえばGitHub Actionsでは、actions/setup-dotnetでSDKバージョンを指定します。
YAML- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.0.x'
ローカルとCIでSDKをそろえることが、C# バージョン関連のトラブル対策になります。
8-3. SDKを更新してもC#バージョンが変わらない
.NET SDKを更新してもC# バージョンが変わらない場合、TargetFrameworkが古いままになっている可能性があります。
たとえば、SDKに.NET 10を入れていても、プロジェクトが次のままなら、
XML<TargetFramework>net6.0</TargetFramework>
既定のC# バージョンはC# 10です。
C# 14を使いたいなら、TargetFrameworkをnet10.0に変更します。
XML<TargetFramework>net10.0</TargetFramework>
SDKを入れるだけではなく、プロジェクト側のTargetFrameworkも確認しましょう。
8-4. LangVersionを指定しても反映されない
LangVersionを指定しても反映されない場合は、次の点を確認します。
まず、.csprojの正しいPropertyGroupに書かれているか確認します。
XML<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<LangVersion>14.0</LangVersion>
</PropertyGroup>
次に、Directory.Build.propsや別のMSBuild設定で上書きされていないか確認します。
また、ソリューション内の別プロジェクトをビルドしているだけというケースもあります。エラーが出ているプロジェクトの.csprojを確認しましょう。
最後に、#error versionを使って実際のC# バージョンを確認します。
8-5. 古いプロジェクトで最新構文が使えない
古い.NET Frameworkや古いSDKを使っているプロジェクトでは、最新のC#構文が使えないことがあります。
短期的な対処としては、使用する構文を現在のC# バージョンに合わせる方法があります。長期的には、TargetFrameworkの更新、SDKの更新、Visual Studioの更新を検討しましょう。
特に、.NET Frameworkプロジェクトでは既定がC# 7.3であるため、C# 8.0以降の構文を前提にしたコードを導入するときは注意が必要です。
9. C#バージョンに関するよくある質問
9-1. C#の最新バージョンは何ですか?
2026年6月時点で、安定版の最新C# バージョンはC# 14です。C# 14は.NET 10に対応します。プレビュー版としてはC# 15が案内されており、.NET 11 preview SDKで試せます。
実務では、安定性を重視するならC# 14、将来機能の検証をしたいならC# 15 previewという考え方になります。
9-2. 自分の環境でC#のバージョンを確認するコマンドは?
.NET SDKの確認は次のコマンドです。
Bashdotnet --version
dotnet --list-sdks
dotnet --info
プロジェクトで実際に使われているC# バージョンを確認するには、コードに一時的に次を追加します。
C##error version
ビルド時に、現在のコンパイラと言語バージョンが表示されます。
9-3. C#のバージョンと.NETのバージョンは同じですか?
同じではありません。
C#はプログラミング言語のバージョンです。.NETはアプリを実行するためのプラットフォームやライブラリです。
ただし、現在の.NETでは、TargetFrameworkによって既定のC# バージョンが決まります。たとえば、.NET 8ではC# 12、.NET 10ではC# 14が既定です。
9-4. C#だけをアップデートできますか?
技術的には、LangVersionを指定することでC# バージョンだけを明示的に変えることはできます。
XML<LangVersion>14.0</LangVersion>
しかし、TargetFrameworkと対応しないC# バージョンを指定すると、サポート対象外になったり、ランタイムやライブラリとの不整合が起きたりする可能性があります。基本的には、C#だけを無理に上げるのではなく、.NET SDKやTargetFrameworkと合わせて更新するのがおすすめです。
9-5. 初心者はどのC#バージョンを学ぶべきですか?
初心者は、現在広く使われている.NETのLTS版に対応するC# バージョンを学ぶのがおすすめです。
これから学ぶなら、.NET 8または.NET 10を使い、C# 12〜C# 14の範囲で学ぶとよいでしょう。ただし、最初から最新構文をすべて覚える必要はありません。
まずは、変数、条件分岐、ループ、クラス、メソッド、コレクション、例外、LINQ、非同期処理を学び、その後にrecord、Nullable参照型、required、プライマリコンストラクターなどを学ぶと理解しやすくなります。
まとめ
C# バージョンは、プロジェクトで使える構文や言語機能を決める重要な要素です。C#、.NET、Visual Studio、SDK、TargetFrameworkはそれぞれ役割が異なりますが、実際の開発では密接に関係しています。
基本的には、LangVersionを無理に指定するのではなく、TargetFrameworkに応じた既定のC# バージョンを使うのが安全です。.NET 8ならC# 12、.NET 10ならC# 14というように、.NETのバージョンに合わせて考えると分かりやすくなります。
C# バージョンを確認したい場合は、dotnet --infoやdotnet --list-sdksでSDKを確認し、実際の言語バージョンは#error versionで確認します。変更したい場合は、.csprojのLangVersionやDirectory.Build.propsを使います。
新規開発では、安定版の.NETとそれに対応するC# バージョンを選びましょう。既存プロジェクトでは、無理に最新化せず、SDK、TargetFramework、CI/CD環境、チームの開発環境をそろえながら段階的に移行することが大切です。

