C# 12 の新機能

C# 12 には、次の新機能が含まれます。 これらの機能は、最新の Visual Studio 2022 バージョンまたは .NET 8 SDK を使用して試すことができます。

C# 12 は .NET 8 でサポートされています。 詳細については、「C# 言語のバージョン管理」を参照してください。

最新の .NET 8 SDK は .NET のダウンロード ページからダウンロードできます。 .NET 8 SDK が含まれている Visual Studio 2022 をダウンロードすることもできます。

Note

これらの機能に関するご意見とご感想をお寄せください。 これらの新機能のいずれかに問題がある場合は、dotnet/roslyn リポジトリに新しい問題を作成します。

プライマリ コンストラクター

すべての classstruct で、プライマリ コンストラクターを作成できるようになりました。 プライマリ コンストラクターは、record 型に制限されなくなりました。 プライマリ コンストラクターのパラメーターは、クラスの本体全体のスコープに含まれます。 プライマリ コンストラクターのすべてのパラメーターが確実に割り当てられるようにするには、明示的に宣言されたすべてのコンストラクターで、this() 構文を使ってプライマリ コンストラクターを呼び出す必要があります。 プライマリ コンストラクターを class に追加すると、コンパイラで暗黙的なパラメーターなしのコンストラクターが宣言されなくなります。 struct では、暗黙的なパラメーターなしのコンストラクターによってすべてのフィールドが初期化され、これにはプライマリ コンストラクター パラメーターの 0 ビット パターンへの初期化が含まれます。

コンパイラは、record 型 (record class または record struct 型) についてのみプライマリ コンストラクター パラメーターのパブリック プロパティを生成します。 非レコード クラスと構造体では、プライマリ コンストラクター パラメーターに対するこの動作が常に必要であるとは限りません。

プライマリ コンストラクターの詳細については、プライマリ コンストラクターの探索に関するチュートリアルと、インスタンス コンストラクターに関する記事を参照してください。

コレクション式

コレクション式は、共通のコレクション値を作成するための新しい簡潔な構文を導入します。 これらの値に他のコレクションをインライン化するために、スプレッド演算子 .. を使用できます。

外部 BCL サポートの必要なく、いくつかのコレクションのような型を作成できます。 これらの型には、次のようなものがあります。

次に、コレクション式の使用例を示します。

// Create an array:
int[] a = [1, 2, 3, 4, 5, 6, 7, 8];

// Create a list:
List<string> b = ["one", "two", "three"];

// Create a span
Span<char> c  = ['a', 'b', 'c', 'd', 'e', 'f', 'h', 'i'];

// Create a jagged 2D array:
int[][] twoD = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];

// Create a jagged 2D array from variables:
int[] row0 = [1, 2, 3];
int[] row1 = [4, 5, 6];
int[] row2 = [7, 8, 9];
int[][] twoDFromVariables = [row0, row1, row2];

コレクション式のスプレッド演算子である .. は、その引数をコレクションの要素に置き換えます。 引数はコレクション型である必要があります。 次の例はスプレッド演算子の動作を示します。

int[] row0 = [1, 2, 3];
int[] row1 = [4, 5, 6];
int[] row2 = [7, 8, 9];
int[] single = [.. row0, .. row1, .. row2];
foreach (var element in single)
{
    Console.Write($"{element}, ");
}
// output:
// 1, 2, 3, 4, 5, 6, 7, 8, 9,

スプレッド演算子のオペランドは、列挙可能な式です。 スプレッド演算子は、列挙式の各要素を評価します。

要素のコレクションが必要な場合は、どこでもコレクション式を使用できます。 コレクションの初期値を指定したり、コレクション型を受け取るメソッドの引数として渡したりすることができます。 コレクション式の詳細については、コレクション式言語リファレンスの記事、または機能仕様を参照してください。

ref readonly パラメーター

C# では、読み取り専用参照を渡す方法として in パラメーターが追加されました。 in パラメーターは変数と値の両方を許可し、引数に注釈を付けずに使用できます。

ref readonly パラメーターを追加すると、ref パラメーターまたは in パラメーターを使用している可能性がある API がより明確になります:

  • in より前に作成された API は、引数が変更されていない場合でも使用 ref できます。 これらの API は、ref readonly で更新できます。 ref パラメーターが in に変更された場合と同様に、呼び出し元にとって破壊的な変更にはなりません。 たとえば System.Runtime.InteropServices.Marshal.QueryInterface です。
  • パラメーター in を受け取るが、論理的には変数を必要な API。 値式 (value expression) は機能しません。 たとえば System.ReadOnlySpan<T>.ReadOnlySpan<T>(T) です。
  • 変数が必要であるが、その変数を変更しないために ref を使用する API。 たとえば System.Runtime.CompilerServices.Unsafe.IsNullRef です。

ref readonly パラメーターの詳細については、言語リファレンスのパラメーター修飾子または 「ref 読み取り専用パラメーター機能の仕様」を参照してください。

既定のラムダ パラメーター

ラムダ式のパラメーターに既定値を定義できるようになりました。 構文と規則は、任意のメソッドまたはローカル関数に引数の既定値を追加する場合と同じです。

ラムダ式での既定のパラメーターについて詳しくは、ラムダ式に関する記事をご覧ください。

任意の型の別名設定

using 別名ディレクティブを使うと、名前付き型だけでなく、任意の型に別名を設定できます。 つまり、タプル型、配列型、ポインター型、またはその他の安全でない型のセマンティック別名を作成できます。 詳細については、「機能の仕様」を参照してください。

インライン配列

インライン配列は、アプリのパフォーマンスを向上させるために、ランタイム チームや他のライブラリ作成者が使用します。 インライン配列を使用すると、開発者は、struct 型でサイズが固定の配列を作成できます。 インライン バッファーを持つ構造体により、安全でない固定サイズ バッファーと同様のパフォーマンス特性が期待できます。 独自のインライン配列は宣言しないこともありますが、ランタイム API から System.Span<T> オブジェクトまたは System.ReadOnlySpan<T> オブジェクトとして公開されている場合は、それらを透過的に使用できます。

インライン配列の宣言は、以下の struct に類似です:

[System.Runtime.CompilerServices.InlineArray(10)]
public struct Buffer
{
    private int _element0;
}

使用方法は他の配列と同様です。

var buffer = new Buffer();
for (int i = 0; i < 10; i++)
{
    buffer[i] = i;
}

foreach (var i in buffer)
{
    Console.WriteLine(i);
}

違いは、インライン配列に関する既知の情報を、コンパイラが利用できるということです。 インライン配列は、他の配列と同様に使用できます。 インライン配列を宣言する方法の詳細については、structに関する言語リファレンスを参照してください。

試験段階の属性

型、メソッド、またはアセンブリには、試験的機能を示す System.Diagnostics.CodeAnalysis.ExperimentalAttribute マークを付けることができます。 ExperimentalAttribute の注釈が付いているメソッドまたは型にアクセスする場合、コンパイラから警告が出ます。 Experimental 属性でマークされたアセンブリに含まれる、すべての型は実験段階です。 詳細については、「コンパイラによって読み取られる一般的な属性」、または「機能仕様」の記事を参照してください。

インターセプター

警告

インターセプターは試験的な機能であり、C# 12 のプレビュー モードで使用できます。 この機能は、今後のリリースで破壊的変更を受ける、または削除される可能性があります。 そのため、運用環境またはリリースされたアプリケーションにはお勧めしません。

インターセプターを使用するには、ユーザー プロジェクトで <InterceptorsPreviewNamespaces> プロパティを指定する必要があります。 これは、インターセプターを含むことができる名前空間の一覧です。

例: <InterceptorsPreviewNamespaces>$(InterceptorsPreviewNamespaces);Microsoft.AspNetCore.Http.Generated;MyLibrary.Generated</InterceptorsPreviewNamespaces>

インターセプターは、インターセプト可能なメソッドに対する呼び出しを、コンパイル時にそれ自体の呼び出しで宣言的に置き換えることができるメソッドです。 この置換は、インターセプターにインターセプトする呼び出しのソースの場所を宣言させることによって発生します。 インターセプターにより、たとえばソース ジェネレーター内で、コンパイルに新しいコードを追加して既存コードのセマンティクスを変更する機能が制限されます。

インターセプターはソース ジェネレーターの一部として、既存ソース コンパイルにコードを追加するのではなく、コードを変更するために使用します。 ソース ジェネレーターは、インターセプト可能メソッドの呼び出しを "インターセプター" メソッドの呼び出しで置き換えます。

インターセプターの試用をご検討の場合は、「機能仕様」をお読みになり詳細をご確認ください。 この機能を使用する場合は、この実験機能の機能仕様のどんな変更も見逃さないように注意してください。 この機能が完成したら、このサイトにさらにガイダンスを追加します。

関連項目