C#におけるclassとrecordの違い

C#では、classrecordはいずれもデータを表現する型を定義するためのキーワードですが、それぞれ異なる特徴を持ちます。本資料では、classrecordの違い、それぞれの特徴や使い分けについて解説します。


1. classの特徴

classは、C#におけるオブジェクト指向プログラミングを実現するための基本的な型です。

主な特徴

  1. ミュータブルな設計が主流
    • プロパティやフィールドの値を変更可能。
    • 例: ゲームのキャラクターやアプリケーションの設定など。
  2. 参照型
    • ヒープに配置され、変数にはインスタンスの参照が格納される。
  3. オブジェクトの同一性を重要視
    • デフォルトでは、Equalsメソッドや==演算子は参照の同一性を比較。
  4. 柔軟な構造
    • 継承、インターフェースの実装、多態性などのオブジェクト指向の要素をサポート。

コード例

class Person
{
    public string Name { get; set; }
    public int Age { get; set; }

    public override string ToString() => $"{Name}, {Age} years old";
}

2. recordの特徴

recordは、C# 9.0で導入された型で、主にイミュータブルなデータを表現するために使用されます。

主な特徴

  1. イミュータブルな設計が主流
    • 作成後にデータを変更しないことを前提に設計。
    • プロパティは通常initアクセサーやreadonlyを使用。
  2. 値の同一性を重要視
    • Equalsメソッドや==演算子で、オブジェクトの中身(プロパティの値)が同一かを比較。
  3. コピーの容易さ
    • with式を使用して、新しいインスタンスを簡単に作成可能。
  4. デフォルトのToString実装
    • プロパティの値を含む文字列を返す形式が自動生成される。

コード例

record Person(string Name, int Age);

var person1 = new Person("Alice", 30);
var person2 = person1 with { Age = 31 }; // Ageだけ変更した新しいインスタンス

イミュータブルなrecordの記述例

recordでプロパティを完全にイミュータブルに保つ場合には、initアクセサーを使用します。

record Person
{
    public string Name { get; init; }
    public int Age { get; init; }
}

var originalPerson = new Person { Name = "Alice", Age = 30 };
// originalPerson.Name = "Jhon"; // これはエラーになる

var updatedPerson = originalPerson with { Name = "Jhon" }; // 新しいインスタンスを作成
Console.WriteLine(updatedPerson.Name); // 出力: Jhon

3. classrecordの比較

特徴classrecord
基本目的オブジェクト指向データ表現
同一性の比較参照の同一性値の同一性
ミュータブル性ミュータブル(変更可能)イミュータブル(変更不可が主流)
デフォルトのToStringオーバーライドが必要自動生成
コピーのサポート自力で実装with式で簡単
主な用途振る舞いやロジックを持つオブジェクトデータ転送やデータ保存

4. 使い分けの指針

classを使う場面

  • 状態や振る舞いを持つオブジェクトを作成したいとき。
  • ミュータブルなオブジェクトが必要な場合。
  • 継承やポリモーフィズムを多用する場合。

recordを使う場面

  • イミュータブルなデータ構造が必要な場合。
  • 比較が頻繁に行われるデータ(例: IDや属性での比較)。
  • データ転送オブジェクト(DTO)や設定オブジェクトを定義する場合。

5. まとめ

  • class は、オブジェクトの状態や振る舞いを重視する場合に適している。
  • record は、データの値や構造を重視する場合に適している。

これらの違いを理解し、適切に使い分けることで、効率的でメンテナンス性の高いコードを実現できます。

C#,record

Posted by hidepon