C# 13 の新機能
C# 13 には、次の新機能が含まれています。 最新の Visual Studio 2022 バージョンまたは .NET 9 SDKを使用して、これらの機能を試すことができます。
-
params
コレクション - 新しい
lock
型とセマンティクス。 - 新しいエスケープ シーケンス -
\e
。 - メソッド グループ自然型の改善
- オブジェクト初期化子での暗黙的インデクサー アクセス
- イテレーターと非同期メソッドで、
ref
ローカル変数とunsafe
コンテキストを有効にする ref struct
型を有効にして、インターフェイスを実装します。- ジェネリックの型パラメーターの引数として ref 構造体型を許可します。
- 部分プロパティとインデクサー が
partial
型で許可されるようになりました。 - オーバーロード解決の優先順位 を使用すると、ライブラリ作成者は 1 つのオーバーロードを他のオーバーロードよりも優れたオーバーロードとして指定できます。
Visual Studio 17.12 以降、C# 13 には、プレビュー機能として field
コンテキスト キーワードが含まれています。
C# 13 は、.NET 9 でサポートされています。 詳細については、C# 言語のバージョン管理 を参照してください。
最新の .NET 9 SDK は、.NET ダウンロード ページからダウンロードできます。 .NET 9 SDK を含む Visual Studio 2022 ダウンロードすることもできます。
新しい機能は、パブリック プレビュー リリースで利用可能になると、[C# の新機能] ページに追加されます。 roslyn 機能ステータス ページのワーキング セット セクションでは、今後の機能がメイン ブランチにマージされる時期を追跡します。
C# 13 で導入された破壊的変更については、破壊的変更に関する記事を参照してください。
手記
これらの機能に関するフィードバックに関心があります。 これらの新機能のいずれかに問題がある場合は、dotnet/roslyn リポジトリで新しい問題を作成してください。
params
コレクション
params
修飾子は配列型に限定されません。 System.Span<T>、System.ReadOnlySpan<T>、System.Collections.Generic.IEnumerable<T> を実装し、Add
メソッドを持つ型など、認識された任意のコレクション型で params
を使用できるようになりました。 具象型に加えて、インターフェイス System.Collections.Generic.IEnumerable<T>、System.Collections.Generic.IReadOnlyCollection<T>、System.Collections.Generic.IReadOnlyList<T>、System.Collections.Generic.ICollection<T>、および System.Collections.Generic.IList<T> も使用できます。
インターフェイス型を使用すると、コンパイラは指定された引数のストレージを合成します。 詳細については、params
コレクションの機能仕様を参照してください。
たとえば、メソッド宣言では、スパンを params
パラメーターとして宣言できます。
public void Concat<T>(params ReadOnlySpan<T> items)
{
for (int i = 0; i < items.Length; i++)
{
Console.Write(items[i]);
Console.Write(" ");
}
Console.WriteLine();
}
新しいロック オブジェクト
.NET 9 ランタイムには、スレッド同期用の新しい型 (System.Threading.Lock 型) が含まれています。 この型は、API を使用してスレッドの同期を向上させます。 Lock.EnterScope() メソッドは、排他的スコープを入力します。 そこから返される ref struct
は、排他スコープを終了する Dispose()
パターンをサポートします。
C# lock
ステートメントは、ロックのターゲットが Lock
オブジェクトであるかどうかを認識します。 その場合は、System.Threading.Monitorを使用する従来の API ではなく、更新された API を使用します。 コンパイラは、Lock
オブジェクトを別の型に変換し、Monitor
ベースのコードが生成されるかどうかを認識します。 詳細については、新しいロック オブジェクトの機能仕様を参照してください。
この機能を使用すると、lock
するオブジェクトの種類を変更することで、新しいライブラリの種類の利点を得ることができます。 他のコードを変更する必要はありません。
新しいエスケープ シーケンス
ESCAPE
文字 (Unicode U+001B
) の文字リテラルのエスケープ シーケンスとして \e
を使用できます。 以前は、\u001b
または \x1b
を使用しました。 1b
の後の次の文字が有効な 16 進数の場合、それらの文字がエスケープ シーケンスの一部になったため、\x1b
を使用することはお勧めしません。
メソッド グループ自然型
この機能により、メソッド グループを含むオーバーロードの解決に対して小さな最適化が行われます。 メソッドグループ は、同じ名前のメソッドとそのすべてのオーバーロードから構成されています。 以前の動作は、コンパイラがメソッド グループの候補メソッドの完全なセットを構築するためでした。 自然型が必要な場合、自然型は候補メソッドの完全なセットから決定されました。
新しい動作では、各スコープで候補メソッドのセットを排除し、該当しない候補メソッドを削除します。 通常、削除されたメソッドは、間違ったアリティを持つジェネリック メソッド、または満たされていない制約です。 このプロセスは、候補のメソッドが見つからない場合にのみ、次の外部スコープに進みます。 このプロセスは、オーバーロード解決の一般的なアルゴリズムに従います。 特定のスコープで見つかったすべての候補メソッドが一致しない場合、メソッド グループには自然な型はありません。
提案仕様の変更の詳細を読むことができます。
インデックスへの暗黙のアクセス
暗黙的な "from the end" インデックス演算子 (^
) は、オブジェクト初期化子式で許可されるようになりました。 たとえば、次のコードに示すように、オブジェクト初期化子で配列を初期化できるようになりました。
public class TimerRemaining
{
public int[] buffer { get; set; } = new int[10];
}
var countdown = new TimerRemaining()
{
buffer =
{
[^1] = 0,
[^2] = 1,
[^3] = 2,
[^4] = 3,
[^5] = 4,
[^6] = 5,
[^7] = 6,
[^8] = 7,
[^9] = 8,
[^10] = 9
}
};
TimerRemaining
クラスには、長さ 10 に初期化された buffer
配列が含まれています。 前の例では、"from the end" インデックス演算子 (^
) を使用してこの配列に値を割り当て、実質的に 9 から 0 までカウントダウンする配列を作成します。
C# 13 より前のバージョンでは、^
演算子をオブジェクト初期化子で使用することはできません。 要素のインデックスを前面から作成する必要があります。
反復子の ref
と unsafe
および async
メソッド
この機能と次の 2 つの機能により、ref struct
型で新しいコンストラクトを使用できます。 独自の ref struct
型を記述しない限り、これらを使用しません。 おそらく、System.Span<T>とSystem.ReadOnlySpan<T>がより多くの機能を獲得することで、間接的なメリットが得られるでしょう。
C# 13 より前のバージョンでは、反復子メソッド (yield return
を使用するメソッド) と async
メソッドは、ローカル ref
変数を宣言することも、unsafe
コンテキストを持つこともできませんでした。
C# 13 では、async
メソッドは、ref
ローカル変数または ref struct
型のローカル変数を宣言できます。 ただし、これらの変数には、await
境界を越えてアクセスすることはできません。 どちらも、yield return
境界を越えてアクセスすることはできません。
この緩やかな制限により、コンパイラは、より多くの場所で ref
ローカル変数と ref struct
型を検証可能に安全に使用できます。 これらのメソッドでは、System.ReadOnlySpan<T> のような型を安全に使用できます。 安全規則に違反しているかどうかをコンパイラから通知されます。
同様に、C# 13 では反復子メソッドで unsafe
コンテキストを使用できます。 ただし、すべての yield return
ステートメントと yield break
ステートメントは、安全なコンテキストにある必要があります。
allows ref struct
C# 13 より前では、ref struct
型をジェネリック型またはメソッドの型引数として宣言できませんでした。 これで、ジェネリック型宣言にアンチ制約(allows ref struct
)を追加できるようになりました。 この反制約では、その型パラメーターに指定された型引数を ref struct
型にできることを宣言します。 コンパイラは、その型パラメーターのすべてのインスタンスに ref 安全規則を適用します。
たとえば、次のコードのようなジェネリック型を宣言できます。
public class C<T> where T : allows ref struct
{
// Use T as a ref struct:
public void M(scoped T p)
{
// The parameter p must follow ref safety rules
}
}
これにより、System.Span<T> や System.ReadOnlySpan<T> などの型を汎用アルゴリズムで使用できます (該当する場合)。 詳細については、where
の更新プログラムと、一般的な制約 に関するプログラミング ガイドの記事を参照してください。
ref struct
インターフェイス
C# 13 より前では、ref struct
型はインターフェイスの実装を許可されていませんでした。 C# 13 以降では、可能です。 ref struct
型がインターフェイスを実装することを宣言できます。 ただし、ref 安全規則を確保するために、ref struct
型をインターフェイス型に変換することはできません。 その変換はボックス化変換であり、参照の安全性を侵害する可能性があります。 ref struct
の明示的なインターフェイス メソッド宣言は、その型パラメーターが allows ref struct
という条件を満たす場合にのみ、型パラメーターを介してアクセス可能です。 また、ref struct
型は、既定の実装を持つメソッドを含め、インターフェイスで宣言されているすべてのメソッドを実装する必要があります。
ref struct
型 の更新と allows ref struct
ジェネリック制約の追加について詳しく知る。
その他の部分メンバー
C# 13 では、partial
プロパティと partial
インデクサーを宣言できます。 一般に、部分プロパティとインデクサーは、partial
メソッドと同じ規則に従います。宣言 を宣言する を 1 つ作成し、1 つ 宣言実装します。 2 つの宣言のシグネチャが一致している必要があります。 制限の1つは、が部分プロパティを実装する際に、自動プロパティ宣言 を使用できないことです。 本体を宣言しないプロパティは、宣言型宣言とみなされます。
public partial class C
{
// Declaring declaration
public partial string Name { get; set; }
}
public partial class C
{
// implementation declaration:
private string _name;
public partial string Name
{
get => _name;
set => _name = value;
}
}
詳細については、部分メンバー に関する記事を参照してください。
オーバーロード解決の優先順位
C# 13 では、コンパイラは、1 つのオーバーロードを別のオーバーロードよりも優先する OverloadResolutionPriorityAttribute を認識します。 ライブラリ作成者は、この属性を使用して、既存のオーバーロードよりも新しいより優れたオーバーロードが優先されるようにすることができます。 たとえば、パフォーマンスの高い新しいオーバーロードを追加できます。 ライブラリを使用する既存のコードを中断する必要はありませんが、ユーザーが再コンパイルするときに新しいバージョンに更新する必要があります。 オーバーロード解決優先度 を使用して、どのオーバーロードを優先するかをコンパイラに通知できます。 優先順位が最も高いオーバーロードが優先されます。
この機能は、ライブラリ作成者が新しいオーバーロードを追加するときにあいまいさを回避することを目的としています。 ライブラリの作成者は、混乱を避けるために、この属性に注意を払う必要があります。
field
キーワード
field
コンテキスト キーワードは、プレビュー機能として C# 13 にあります。 トークン field
は、プロパティ アクセサーのコンパイラ合成バッキング フィールドにアクセスします。 これにより、型宣言で明示的なバッキング フィールドを宣言せずにアクセサー本体を記述できます。 フィールドでサポートされたプロパティの 1 つまたは両方のアクセサーの本体を宣言できます。
field
機能はプレビュー機能としてリリースされます。 私たちはそれを使用してあなたの経験から学びたいです。 field
というフィールドが含まれる型のコードを読み取る際には、破壊的変更が発生する可能性や混乱を招く恐れがあります。 @field
または this.field
を使用して、field
キーワードと識別子の間であいまいさを解消できます。
重要
field
キーワードは、C# 13 のプレビュー機能です。 field
コンテキスト キーワードを使用するには、.NET 9 を使用し、<LangVersion>
要素をプロジェクト ファイルに preview
するように設定する必要があります。
field
という名前のフィールドを持つクラスでは、field
キーワード機能の使用に注意する必要があります。 新しい field
キーワードは、プロパティ アクセサーのスコープ内の field
という名前のフィールドをシャドウします。 field
変数の名前を変更するか、@
トークンを使用して field
識別子を @field
として参照できます。 詳細については、field
キーワードの機能仕様を参照してください。
この機能を試してフィードバックがある場合は、csharplang
リポジトリの 機能の問題 に追加します。
関連項目
- .NET 9 の新機能
.NET