2023 年 11 月に C# 12 が正式リリースされました!大変おめでたいし、Microsoft 本社の C# 開発チームの方々には (毎年のことながら) 感謝申し上げます...!
で、C# 12 で導入された目玉機能のひとつに Primary Constructors というものがあります。必須コンストラクタを record
型っぽい記述で書けるようにする機能です。
class A(int x) { public int X { get; } = x; }
これは C# 6 の頃から導入が検討されていた機能で、約 10 年弱の検討と改良を経て正式に採用されました。以下の記事は 2014/6/16 に書いたものですが、リリース直前に搭載が見送られたことまで残っていました。過去の自分、エラいね...w
正式リリースされたけど使うことに抵抗があった
正直なところ、Primary Constructors を自分が書くコードに採用するのには前向きではありませんでした。特に以下のふたつが理由です。
- コンストラクタ引数をキャプチャして利用できてしまう
- 特に Backing Field が 2 重にできてしまう可能性を払拭できるか不安
- https://ufcpp.net/study/csharp/oo_construct.html#primary-constructor
- コンストラクタ内で何か処理を書きたくなったら通常のコンストラクタに変換しないといけない
「1」は Primary Constructors の挙動をちゃんと理解しないとダメで、自分がよくてもチーム全体で統制できるかが不安でした。「2」は単純に面倒だからです。通常のコンストラクタから Primary Constructors への変換機能は Visual Studio に搭載されているので簡単ですが、逆がないのが懸念でした。
けど「使っていこう」と決心した
しばらく抵抗感が強かったにも拘らず心変わりした理由は次の通りです。
- .editorconfig を使って
CS9124
をエラーにすることで多重 Backing Field 問題を防げる- C# の挙動を詳細まで把握していないチームメイトに対してもある程度の強制力を持って対処できる
- DI 部分に限ればコンストラクタ内に処理を書くことがまずない
- ので、そこに限れば「十分飲み込める」と思えるようになってきた
- Visual Studio の IntelliSense が多重 Backing Field 問題を緩和していることに気付いた
特に最後の IntelliSense の挙動を知ったことが大きいです。「百聞は一見に如かず」ということで以下のキャプチャをご覧ください。
プロパティに引数を代入しさえすれば IntelliSense にすら表示されない という神対応!これによって「コードを書いてから CS9124
で間違いに気付くのではなく、コードを書く瞬間から間違いを起こさせない」ことになるので抵抗感がグッと下がりました。
まとめ
今後は Primary Constructors にも書き慣れていきたい所存。しかし、この IntelliSense はどうやって対応しているんでしょうね。決め打ちの特別対応なのかな。