この章のテーマ §
recordとwith演算子を学びます。読み出し専用のクラスの作り方と、その書き換え方を学びます。
前提知識 §
Console.WriteLineメソッド, 文字列の基礎, 変数の基礎, クラスの基礎, 構造体の基礎, string型
解説 §
recordはclassやstructを修飾するキーワードです。しかし、record単体でも使用できます。これは読み出し専用のクラスや構造体を作成するための機能です。一度作成したあとで変化しないオブジェクトを【不変のオブジェクト】といい、プログラムが理解しやすいので利用は推奨されています。それを支援するためのキーワードがrecordです。
recordキーワードを使うと、短縮形で短く読み出し専用のクラスを定義できます。サンプルソースのpublic record Person(string FirstName, string LastName);は、string FirstName, string LastNameの2つの読み出し専用プロパティを持つクラスPersonを定義しています。コンストラクタの2つの引数で初期値を与えてそのあとでは一切変更を許しません。
しかし、これだけでは不便なのでwith演算子が用意されています。with演算子は、指定メンバーだけを書き換えた新しいオブジェクトを作成します。サンプルソースのtaro with { FirstName="ウルトラマン" };がそれに該当します。これはFirstNameだけ書き換えてLastNameは書き換えません。
罠の数々 §
- recordキーワードを使っても読み書き可能なクラスが作成できるが、お勧めではない
- 筆者が考えたステート集約プログラミングでも、recordは主役である。recordはステート集約プログラミングをするための機能と言っても過言ではない。C#にrecordが実装されたときは「これだ!」と言ったものである。(ステート集約プログラミング入門: ソフトの生産性を向上させる秘密のスパイス! )
- サンプルソースではFirstNameに山田を入れているが、本来ならFirstNameに太郎が入る方が自然である
- 特に理由がない限り、通常クラスよりもrecordを使うことが筆者のお勧めである
参考リンク §
レコード型を作成する
レコード (C# リファレンス)
サンプルソース: kw_record §
var taro = new Person("山田", "太郎");
Console.WriteLine($"{taro.FirstName}{taro.LastName}");
// 以下はできない
// taro.FirstName = "ウルトラマン";
taro = taro with { FirstName="ウルトラマン" };
Console.WriteLine($"{taro.FirstName}{taro.LastName}");
public record Person(string FirstName, string LastName);
実行結果 §
山田太郎
ウルトラマン太郎
リポジトリ §
https://github.com/autumn009/CSharpPrimer2
練習問題 §
間違った説明を選ぼう。
- recordは読み出し専用だがwith演算子で書き換えられる
- recordは読み出し専用ではない
- with演算子にはメンバーの値を変更してオブジェクトを変化させる機能はない
- 厳密に言うとrecordという型は存在しない。クラスまたは構造体の特殊なケースがrecordである
- recordの利用は筆者のお勧めである
[[解答]]