C# 14 を使いたい! そう思っていますね? わかります。私もです。
.NET 10 ももうリリースになります。となれば当然に皆さんお待ちかねの C# 14 を皆が使い始めます。私も使います。
■ 前回までの C# 14
C# 14 の新機能ですが、前回までの記事で機能リスト的には Preview 版の時に追いかけていた内容とほぼ同じ、コードもほぼそのまま、ほぼ何もしなくてもビルドできるとわかりました。
■ C# 14 の動画
こちらで C# 14 が語られています。
その中で気になることを知りました。
■ 知った機能を使ったコード
Console.WriteLine((new A { MyProperty = 10 } - new A { MyProperty = 3 }).MyProperty); // 出力は 「7」 class A { public int? MyProperty { get; set; } } static class Ex2 { extension(A) { public static A operator -(A a, A b) => new A { MyProperty = a?.MyProperty - b?.MyProperty }; } }
新しい拡張メンバーの書き方で演算子を定義できます。
■ 演算子オーバーロード
演算子オーバーロードの公式ドキュメントはこちらです。
観てお分かりの通り、演算子オーバーロードは左辺のクラスに 左辺・右辺の値を引数にとる static メソッドを定義ています(二項演算子の場合)。
こんな感じです。
class A { public int? MyProperty { get; set; } public static A operator -(A a, A b) => new A { MyProperty = a?.MyProperty - b?.MyProperty }; }
■ これまでの拡張メソッド
今回演算子オーバーロードは拡張メンバーで書けるとのことですので、昔からの拡張メソッドでも書けたのか? と思い試しに書いてみました。すると驚きの結果に。
なんと! ダメでした。
static class Ex1 { // これはエラー 「'Ex1.operator -(A, A)': 静的クラスにユーザー定義の演算子を含めることはできません」 public static A operator -(A a, A b) => new A { MyProperty = a?.MyProperty - b?.MyProperty }; // これはエラー 「キーワード 'this' は現在のコンテキストでは使用できません」 public static A operator *(this A a, A b) => new A { MyProperty = a?.MyProperty * b?.MyProperty }; }
■ あたらしい拡張メンバー
ちなみに拡張メンバーにも複数の機能があります。型にスタティックメソッドを追加する機能と、インスタンスメンバーを追加する機能です。
結論として、インスタンスメンバーのパターンはダメでした。
static class Ex2 { // これはエラー 「オーバーロード可能な単項演算子が必要です」 extension(A a) { // これはエラー 「User-defined operator 'Ex2.extension(A).operator *(A)' must be declared static and public」 public A operator *(A b) { return new A { MyProperty = a.MyProperty - b?.MyProperty }; } } }
■ これは使えるが
この拡張メンバーでオペレーターオーバーロードする機能・書き方、クラスがごちゃごちゃせずよさそうです。使っていきたい。
問題は、オペレーターオーバーロードをする機会が私には皆無だという点ですが。