2022年01月20日
川俣晶の縁側ソフトウェアnew_C#入門・全キーワード明快解説! total 790 count

recordとwith: 読み出し専用オブジェクトを書き換えろ!

Written By: 川俣 晶連絡先

この章のテーマ §

 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

練習問題 §

 間違った説明を選ぼう。

  1. recordは読み出し専用だがwith演算子で書き換えられる
  2. recordは読み出し専用ではない
  3. with演算子にはメンバーの値を変更してオブジェクトを変化させる機能はない
  4. 厳密に言うとrecordという型は存在しない。クラスまたは構造体の特殊なケースがrecordである
  5. recordの利用は筆者のお勧めである

[[解答]]

単行本情報