導入
struct(値型)をもっと安全・簡潔に書く道具がreadonly struct(中身を変更できない値型)とrecord struct(recordの簡潔さ+値型)です。あわせて、値型をobjectとして扱うときに起こるボックス化という隠れたコストも知っておきましょう。
図解
flowchart TB
S["struct(値型)"] --> RS["readonly struct<br/>不変(変更不可)で安全"]
S --> RCS["record struct<br/>値の等価比較を自動生成"]
V["値型 int"] -->|object に代入| BOX["ボックス化<br/>ヒープに包まれる(コスト)"]
サンプル
var t = new Temperature(25);
Console.WriteLine(t.Fahrenheit); // 77(中身は変更できないが計算は返せる)
// record struct は値どうしの等価比較(==)が自動で入る
var p1 = new PointR(1, 2);
var p2 = new PointR(1, 2);
Console.WriteLine(p1 == p2); // True(中身が同じなら等しい)
// ボックス化: 値型を object として扱うとヒープに包まれる(コスト)
int n = 42;
object boxed = n; // ボックス化(値型 → object)
int back = (int)boxed; // アンボックス化(object → 値型)
Console.WriteLine(back); // 42
// --- 型の定義(トップレベル文の後ろに置く)---
readonly struct Temperature
{
public double Celsius { get; }
public Temperature(double c) => Celsius = c;
public double Fahrenheit => Celsius * 9 / 5 + 32;
}
record struct PointR(int X, int Y);
readonly structは不変な値型。生成後に中身を変えられないので安全(並行処理でも安心)record structはrecordの簡潔さと値型を両立し、値の等価比較(==)が自動で入る- ボックス化は値型を
object(やinterface)として扱うときにヒープへ包む処理。頻発するとコストになる
演習
// TODO: record struct Pair(int A, int B) を定義し、
// new Pair(3, 4) == new Pair(3, 4) の結果を出力してください(True)
Console.WriteLine(new Pair(3, 4) == new Pair(3, 4));
___
- 期待される出力:
True
ヒント1を見る
record struct Pair(int A, int B); を末尾に1行書くだけです
ヒント2を見る
値型のrecordは中身が同じなら==がTrueになります
まとめ
readonly structは不変な値型、record structは値型+自動の等価比較- 値型を
object扱いするとボックス化でヒープに包まれる(コスト) - 小さく不変なデータは
readonly record structが相性抜群
次回: 決まった選択肢を表すenumです。