C# 14 (.NET 10 世代の C# ) の機能、拡張メンバー / extension-members を見てみます。
■ これまでは
拡張メソッドは独特の書き方で実装が必要でした。
■ これからは
また別の独特の書き方で実装ができるようになりました。また、プロパティや静的メソッド、静的プロパティも実装ができます。
■ コードで例
Console.WriteLine("Hello, World!".IsEmpty); Console.WriteLine("".IsEmpty); Console.WriteLine(string.Combine("saitama", "saiko")); Console.WriteLine("Hello, World!".ToArray().IsEmpty); Console.WriteLine("".ToArray().IsEmpty); Console.WriteLine(IEnumerable<int>.Combine(new int[] { }, new int[] { })); // 参考 // 昔ながらの拡張メソッド public static class SampleOldExtension { // 第一引数に this を付けることで拡張メソッドとして定義 public static bool IsEmpty(this int i) => i == 0; } // 拡張メンバー定義 // 一つのクラスに複数定義可能 public static class SampleExtension { // string に対する拡張メンバー // 引数に this は必要ない extension(string s) { // メンバーのシグニチャに this の引数は不要 // 一つの extension ブロックの中に複数定義可能 public bool IsEmpty => (s?.Length ?? 0) == 0; public bool IsEmpty_2 => (s?.Length ?? 0) == 0; // メソッドも定義可能 public bool Empty() => (s?.Length ?? 0) == 0; } // 静的メンバーも定義可能 extension(string) { // 静的メソッド public string Combine(string first, string second) => first + second; // 静的プロパティ public string Empty_2 => string.Empty; } // ジェネリクス型に対する拡張メンバー extension<TSource>(IEnumerable<TSource> source) { public bool IsEmpty => !source.Any(); } // ジェネリクス型に対する拡張メンバー extension<TSource>(IEnumerable<TSource>) { public static IEnumerable<TSource> Combine(IEnumerable<TSource> first, IEnumerable<TSource> second) => Enumerable.Empty<TSource>(); public static IEnumerable<TSource> Identity => Enumerable.Empty<TSource>(); } }
■ 個別に見ていきましょう
昔ながらの書き方と、今回の書き方。
// 参考 // 昔ながらの拡張メソッド public static class SampleOldExtension { // 第一引数に this を付けることで拡張メソッドとして定義 public static bool IsEmpty(this int i) => i == 0; }
// こう使える Console.WriteLine("Hello, World!".Empty()); // 拡張メンバー定義 public static class SampleExtension { // 引数に this は必要ない extension(string s) { // メンバーのシグニチャに this の引数は不要 public bool Empty() => (s?.Length ?? 0) == 0; } }
プロパティ
// こう使える Console.WriteLine("Hello, World!".IsEmpty); public static class SampleExtension { extension(string s) { // 拡張プロパティ public bool IsEmpty => (s?.Length ?? 0) == 0; } }
静的
// こう使える Console.WriteLine(string.Combine("saitama", "saiko")); public static class SampleExtension { // 静的メンバーも定義可能 extension(string) { // 静的メソッド public string Combine(string first, string second) => first + second; // 静的プロパティ public string Empty_2 => string.Empty; } }
ジェネリクス型に対する拡張
// こう使える Console.WriteLine(IEnumerable<int>.Combine(new int[] { }, new int[] { })); public static class SampleExtension { // ジェネリクス型に対する拡張メンバー extension<TSource>(IEnumerable<TSource>) { public static IEnumerable<TSource> Combine(IEnumerable<TSource> first, IEnumerable<TSource> second) => Enumerable.Empty<TSource>(); } }
■ 今回のコード
GitHub に上げています。
■ 備えよう
新機能、いいですね。リリースに備えましょう。