7月10日、Microsoft Developer Blogsで「C# 13: 最新のプレビュー機能を探る(C# 13: Explore the latest preview features)」と題した記事が公開された。この記事では、C# 13の新機能について詳しく紹介されている。以下に、その内容を紹介する。
1. params
コレクションの拡張
C# 13では、params
パラメータがコレクション式で構築できる任意の型に対応するようになり、柔軟性が向上している。params
キーワードは、メソッドのパラメータの前に置くことで、カンマ区切りのリストとして値を渡すことができる。以下はその例である。
public void WriteNames(params string[] names)
=> Console.WriteLine(String.Join(", ", names));
WriteNames("Mads", "Dustin", "Kathleen");
WriteNames(new string[] {"Mads", "Dustin", "Kathleen"});
// 両方とも出力: Mads, Dustin, Kathleen
C# 13では、params
パラメータがコレクション式をサポートする任意の型に対応する。例えば、LINQ式の結果を IEnumerable<T>
パラメータに渡すことも可能である。
public void WriteNames(params IEnumerable<string> names)
=> Console.WriteLine(String.Join(", ", names));
var persons = new List<Person>
{
new Person("Mads", "Torgersen"),
new Person("Dustin", "Campbell"),
new Person("Kathleen", "Dollard")
};
WriteNames(persons.Select(person => person.FirstName));
WriteNames(from p in persons select p.FirstName);
複数の params
オーバーロードを定義することで、利便性とパフォーマンスを向上させることができる。
public void WriteNames(params string[] names)
=> Console.WriteLine(String.Join(", ", names));
public void WriteNames(params ReadOnlySpan<string> names)
=> Console.WriteLine(String.Join(", ", names));
public void WriteNames(params IEnumerable<string> names)
=> Console.WriteLine(String.Join(", ", names));
2. lock
オブジェクト
新しい System.Threading.Lock
型が導入され、これは従来の System.Object
インスタンスに対するロックよりも効率的である。この型は、ほとんどのロック処理において主要なメカニズムとなることが期待されている。lock
ステートメントのターゲットが System.Threading.Lock
オブジェクトである場合、C#は自動的にこの新しいAPIを使用する。
public class MyClass
{
private System.Threading.Lock myLock = new System.Threading.Lock();
public void MyMethod()
{
lock (myLock)
{
// Your code
}
}
}
3. イニシャライザ内での終端からのインデックス
C# 13では、インデックス演算子 ^
を使用して、コレクションの終端からの位置を示すことができる。この機能はイニシャライザでも利用可能である。
class Program
{
static void Main()
{
var x = new Numbers
{
Values =
{
[1] = 111,
[^1] = 999 // C# 13から利用可能
}
};
}
}
class Numbers
{
public int[] Values { get; set; } = new int[10];
}
4. エスケープシーケンス \e
C# 13では、新しいエスケープシーケンス \e
が導入され、従来の \u001b
を使わずに、直接エスケープ文字 ESC
を表現できるようになった。これは特に、VT100/ANSIエスケープコードを用いたターミナル出力で便利である。
// C# 13以前
Console.WriteLine("\u001b[1mThis is a bold text\u001b[0m");
// C# 13から
Console.WriteLine("\e[1mThis is a bold text\e[0m");
5. パーシャルプロパティ
C# 13では、ソースジェネレータをサポートするために、パーシャルプロパティが導入された。これは、C# 9で追加されたパーシャルメソッドに似ている。以下はその例である。
[GeneratedRegex("abc|def")]
private static partial Regex AbcOrDefProperty { get; };
if (AbcOrDefProperty.IsMatch(text))
{
// マッチングテキストに対してアクションを実行
}
6. メソッドグループの自然型の改善
C# 13では、メソッドグループの自然型をより適切に決定するための規則が改善された。これは、メソッド名をカッコなしでデリゲートとして使用する際に役立つ。
Todo GetTodo() => new(Id: 0, Name: "Name");
var f = GetTodo; // fの型はFunc<Todo>
7. ref
と unsafe
の非同期メソッドおよびイテレータでの使用
C# 13では、イテレータメソッドや非同期メソッドで ref
ローカル変数や ref struct
型を使用できるようになった。これらの変数は、awaitやyield returnの境界を超えて保持することはできない。同様に、C# 13では、イテレータメソッドでunsafeコンテキストを使用できるようになった。
詳細は「C# 13: Explore the latest preview features」を参照していただきたい。