C# 11 の新機能

C# 11 では、次の機能が追加されました。

最新の Visual Studio 2022 をダウンロードできます。 .NET 7 SDK を使用してこれらすべての機能を試すこともできます。これは 、.NET ダウンロード ページからダウンロードできます。

Note

これらの機能に関するフィードバックに関心があります。 これらの新機能のいずれかに問題がある場合は、dotnet/roslyn リポジトリに新しい問題を作成します。

汎用属性

基底クラスが である汎用クラスを宣言できます。 この機能により、System.Type パラメーターを必要とする属性の構文がより便利になります。 以前は、Type をコンストラクター パラメーターとして受け取る属性を作成する必要がありました。

// Before C# 11:
public class TypeAttribute : Attribute
{
   public TypeAttribute(Type t) => ParamType = t;

   public Type ParamType { get; }
}

属性を適用するには、typeof 演算子を使用します。

[TypeAttribute(typeof(string))]
public string Method() => default;

この新機能を使用して、代わりに、次のように汎用属性を作成することができます。

// C# 11 feature:
public class GenericAttribute<T> : Attribute { }

次に、属性を使用する型パラメーターを指定します。

[GenericAttribute<string>()]
public string Method() => default;

属性を適用するとき、すべての型パラメーターを提供する必要があります。 言い換えると、ジェネリック型は完全に構築する必要があります。 上記の例では、 属性に引数がないため、空のかっこ (()) を省略できます。

public class GenericType<T>
{
   [GenericAttribute<T>()] // Not allowed! generic attributes must be fully constructed types.
   public string Method() => default;
}

型引数は、typeof 演算子と同じ制限を満たす必要があります。 メタデータ注釈が必要な型は許可されません。 たとえば、次の型は型パラメーターとして使用できません。

  • dynamic
  • string? (または Null 許容参照型)
  • (int X, int Y) (または C# タプル構文を使用するその他のタプル型)。

これらの型は、メタデータで直接表現されません。 これらには、型を記述する注釈が含まれます。 すべてのケースで、代わりに基になる型を使用できます。

  • objectdynamic
  • string (string? の代わり)
  • ValueTuple<int, int> ((int X, int Y) の代わり)

ジェネリック型数値演算のサポート

ジェネリック型数値演算のサポートを有効にする言語機能がいくつかあります。

  • インターフェイスの static virtual メンバー
  • ユーザー定義の checked 演算子
  • 緩和されたシフト演算子
  • 符号なし右シフト演算子

インターフェイスに static abstract または static virtual メンバーを追加して、オーバーロード可能な演算子、他の静的メンバー、静的プロパティを含むインターフェイスを定義できます。 この機能の主なシナリオは、ジェネリック型で算術演算子を使用することです。 たとえば、operator + を実装する型で System.IAdditionOperators<TSelf, TOther, TResult> インターフェイスを実装できます。 他のインターフェイスは、他の算術演算または適切に定義された値を定義します。 新しい構文については、インターフェイスに関する記事を参照してください。 通常、static virtual メソッドを含むインターフェイスはジェネリック インターフェイスです。 さらに、ほとんどの場合は、型パラメーターが宣言されたインターフェイスを実装するという制約が宣言されます。

静的抽象インターフェイス メンバーの確認に関するチュートリアルや、「Preview features in .NET 6 – generic math」のブログ投稿で、詳しく調べたり機能を試したりすることができます。

ジェネリック型数値演算で言語に関する他の要件が作成されました。

  • ''符号なし右シフト演算子'': C# 11 より前では、符号なし右シフトを強制するには、符号付き整数型を符号なし型にキャストし、シフトを実行してから、結果を符号付き型にキャストする必要があります。 C# 11 以降では、>>> (''符号なしシフト演算子'') を使用できます。
  • ''緩やかなシフト演算子の要件'': C# 11 では、2 番目のオペランドが int であるか、暗黙的に int に変換できる必要があるという要件がなくなります。 この変更により、ジェネリック型数値演算インターフェイスを実装する型をこれらの場所で使用できるようになります。
  • ''ユーザー定義の checked および unchecked 演算子'': 開発者は checked および unchecked 算術演算子を定義できるようになりました。 コンパイラにより、現在のコンテキストに基づいて正しいバリアントの呼び出しが生成されます。 checked 演算子の詳細については、算術演算子に関する記事を参照してください。

数値 IntPtrUIntPtr

nint および nuint 型にはそれぞれ System.IntPtr および System.UIntPtr のエイリアスが付くようになりました。

文字列補間の改行

文字列補間の {} の文字内のテキストが複数行にまたがるようになりました。 {} のマーカーの間のテキストが C# として解析されます。 改行を含む有効な C# はすべて許可されます。 この機能により、パターン マッチングの switch 式や LINQ クエリなど、より長い C# 式を使用する文字列補間が読みやすくなります。

改行機能の詳細については、言語リファレンスの文字列補間に関する記事を参照してください。

リスト パターン

"リスト パターン" を使うと、リストまたは配列の要素のシーケンスと照合できるようにパターン マッチングを拡張することができます。 たとえば、sequence が 3 つの整数 (1、2、3) の配列またはリストである場合、sequence is [1, 2, 3]true です。 定数、型、プロパティ、リレーショナル パターンなど、あらゆるパターンを使って要素を照合することができます。 破棄パターン (_) を使うと、任意の 1 つの要素と照合できます。新しい "範囲パターン" (..) を使うと、0 個以上の要素の任意のシーケンスと照合できます。

リスト パターンの詳細については、言語リファレンスのパターン マッチングの記事を参照してください。

改善された、メソッド グループからデリゲートへの変換

メソッド グループ変換の C# 標準に、次の項目が含まれるようになりました。

  • この変換は、これらの参照が既に含まれている既存のデリゲート インスタンスを使用することが許可されます (必須ではありません)。

以前のバージョンの標準では、メソッド グループ変換用に作成されたデリゲート オブジェクトをコンパイラが再利用することを禁止していました。 C# 11 コンパイラは、メソッド グループ変換から作成されたデリゲート オブジェクトをキャッシュし、その 1 つのデリゲート オブジェクトを再利用します。 この機能は、Visual Studio 2022 バージョン 17.2 でプレビュー機能として、および .NET 7 Preview 2 で初めて使用できます。

未加工の文字列リテラル

生文字列リテラル は、文字列リテラルの新しい形式です。 生文字列リテラルには、エスケープ シーケンスを必要とせずに、空白文字、改行、埋め込み引用符、その他の特殊文字を含む任意のテキストを含めることができます。 生文字列リテラルは、少なくとも 3 つの二重引用符 (""") 文字で始まります。 同じ数の二重引用符で囲まれた文字で終わります。 通常、生文字列リテラルでは、1 行に 3 つの二重引用符を使用して文字列を開始し、3 つの二重引用符を別の行で使用して文字列を終了します。 開始の引用符の後と、終わりの引用符の前の改行は、最終的なコンテンツには含まれません。

string longMessage = """
    This is a long message.
    It has several lines.
        Some are indented
                more than others.
    Some should start at the first column.
    Some have "quoted text" in them.
    """;

終わりの二重引用符の左側にある空白文字は、文字列リテラルから削除されます。 生文字列リテラルを文字列補間と組み合わせて、出力テキストに中かっこを含めることができます。 複数の $ 文字は、補間を開始および終了する連続する中かっこの数を示します。

var location = $$"""
   You are at {{{Longitude}}, {{Latitude}}}
   """;

前の例では、2 つの中かっこが補間を開始および終了することを指定しています。 3 番目の繰り返しの開始と終了の中かっこが出力文字列に含まれます。

生文字列リテラルの詳細については、 プログラミング ガイドの文字列に関する記事と、文字列リテラル補間文字列に関する言語リファレンス記事を参照してください。

auto-default 構造体

C# 11 コンパイラでは、コンストラクターの実行の一環として、struct 型のすべてのフィールドが既定値に初期化されます。 この変更は、コンストラクターによって初期化されていないすべてのフィールドまたは自動プロパティが、コンパイラによって自動的に初期化されることを意味します。 現在、コンストラクターによってすべてのフィールドが明確に割り当てられていない構造体がコンパイルされて、明示的に初期化されていないすべてのフィールドに既定値が設定されます。 この変更が構造体の初期化にどのように影響するかの詳細については、構造体に関する記事を参照してください。

string 定数での Span<char> または ReadOnlySpan<char> のパターン マッチ

いくつかのリリースでパターン マッチングを使用して、string に特定の定数値があるかどうかをテストできました。 これで、Span<char> または ReadOnlySpan<char> である変数と同じパターン マッチング ロジックを使用できるようになりました。

拡張 nameof スコープ

型パラメーター名とパラメーター名は、そのメソッドの属性宣言nameof 式で使用する場合に、スコープ内に存在するようになりました。 この機能は、nameof 演算子を使用して、メソッドまたはパラメーター宣言の属性でメソッド パラメーターの名前を指定できることを意味します。 この機能はほとんどの場合、Null 許容分析の属性を追加するのに役立ちます。

UTF-8 の文字列リテラル

文字列リテラルに u8 サフィックスを指定して、UTF-8 文字エンコードを指定できます。 アプリケーションで UTF-8 文字列が必要な場合は、HTTP 文字列定数または同様のテキスト プロトコルに対して、この機能を使用して UTF-8 文字列の作成を簡略化できます。

UTF-8 文字列リテラルの詳細については、組み込みの参照型に関する記事の文字列リテラル セクションを参照してください。

必須メンバー

プロパティとフィールドに required 修飾子を追加して、コンストラクターと呼び出し元にこれらの値を初期化させることができます。 System.Diagnostics.CodeAnalysis.SetsRequiredMembersAttribute をコンストラクターに追加して、コンストラクターが必要な "すべて" のメンバーを初期化することをコンパイラに通知できます。

必要なメンバーの詳細については、プロパティに関する記事の init 専用のセクションを参照してください。

ref フィールドと ref scoped 変数

ref struct 内で ref フィールドを宣言できます。 これにより、特殊な属性がない System.Span<T> や非表示の内部型がサポートされます。

scoped 修飾子は任意の ref 宣言に追加できます。 これにより、参照をエスケープできるスコープが制限されます。

ファイル のローカルの種類

C# 11 以降では、file アクセス修飾子を使用して、可視性が宣言されているソース ファイルをスコープとする型を作成できます。 この機能は、ソース ジェネレーターの作成者が名前の競合を回避するのに役立ちます。 この機能の詳細については、言語リファレンスのファイル スコープ型に関する記事を参照してください。

関連項目