Record型:基礎と構文
record classとrecord structを宣言し、位置指定構文を理解して、recordとclassを比較します。
「Record型:基礎と構文」はCoddyKit上の無料C# Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC# Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C# Academyコースには全4レッスンが含まれています。
レコード型とは
レコード(C# 9 で導入)は、値のセマンティクスを持つ不変データのために設計された参照型です。プロパティの値に基づく等価性、読みやすい ToString()、さらに with 式による非破壊的な変更を自動的にサポートします。
位置指定レコード構文
位置指定構文は最も簡潔な形式です。プロパティ、コンストラクター、分解、等価性がすべて1行から生成されます。
// All in one line:
public record Point(double X, double Y);
public record Person(string FirstName, string LastName, int Age);
// Generated automatically:
// - Primary constructor: new Point(1.0, 2.0)
// - Deconstruct: var (x, y) = point;
// - Equality: p1 == p2 compares X and Y values
// - ToString: "Point { X = 1, Y = 2 }"レコードとクラス
レコードとクラスの主な違いは、既定の等価性と用途です。レコードは構造的等価性(値)を使用し、クラスは参照等価性(同一性)を使用します。
var p1 = new Point(1, 2);
var p2 = new Point(1, 2);
var p3 = p1;
// Record: structural equality
Console.WriteLine(p1 == p2); // True — same values
Console.WriteLine(p1 == p3); // True — same values
// Compare with a class:
var c1 = new PointClass(1, 2);
var c2 = new PointClass(1, 2);
Console.WriteLine(c1 == c2); // False — different referencesレコード構造体
C# 10 では record struct(値型のレコード)が追加されました。レコードクラスと同じ等価性および ToString の機能を持ちながら、構造体と同様にスタックに割り当てられます。
// Record struct: value type, stack-allocated
public record struct Color(byte R, byte G, byte B);
var red = new Color(255, 0, 0);
var red2 = new Color(255, 0, 0);
Console.WriteLine(red == red2); // True — value equality
// Readonly record struct: fully immutable
public readonly record struct Coord(double Lat, double Lng);本体を持つ標準的なレコード宣言
レコードには完全な本体を記述できます。自動生成される等価性と ToString を維持しながら、計算プロパティ、メソッド、コンストラクターでの検証を追加できます。
public record Person(string FirstName, string LastName)
{
// Computed property
public string FullName => $"{FirstName} {LastName}";
// Validation in constructor
public Person : this(FirstName, LastName)
{
if (string.IsNullOrWhiteSpace(FirstName))
throw new ArgumentException("FirstName required");
}
// Method
public Person WithUpperCase() =>
this with { FirstName = FirstName.ToUpper(), LastName = LastName.ToUpper() };
}レコードの継承
レコードは継承をサポートします。派生レコードはプロパティを追加でき、同じ等価性のルールに従います。2つのレコードが等しいのは、型とすべての値が一致する場合だけです。
public record Shape(string Color);
public record Circle(string Color, double Radius) : Shape(Color);
public record Rectangle(string Color, double Width, double Height) : Shape(Color);
var c1 = new Circle("red", 5.0);
var c2 = new Circle("red", 5.0);
var r1 = new Rectangle("red", 5.0, 3.0);
Console.WriteLine(c1 == c2); // True
Console.WriteLine(c1 == r1); // False — different types非位置指定レコードプロパティ
レコードは位置指定パラメーターに限定されません。位置指定プロパティと手動で定義したプロパティを組み合わせたり、プロパティ初期化子で既定値を設定したりできます。
public record Order
{
public int Id { get; init; }
public string CustomerName { get; init; } = "";
public List<OrderLine> Lines { get; init; } = new();
public DateTime CreatedAt { get; init; } = DateTime.UtcNow;
public OrderStatus Status { get; init; } = OrderStatus.Pending;
}
// Initialization:
var order = new Order
{
Id = 42,
CustomerName = "Alice"
// Other props use defaults
};分解
位置指定レコードは Deconstruct メソッドを自動的に生成するため、代入やパターンマッチングで分解できます。
public record Point(double X, double Y);
var p = new Point(3.0, 4.0);
// Deconstruction
var (x, y) = p;
Console.WriteLine($"x={x}, y={y}");
// In switch:
string Describe(Point pt) => pt switch
{
(0, 0) => "Origin",
(double x, 0) => $"On X-axis at {x}",
(0, double y) => $"On Y-axis at {y}",
var (px, py) => $"Point ({px}, {py})"
};DTO としてのレコード
レコードは API のリクエストやレスポンスの DTO に最適です。不変でシリアライズ可能なうえ、自動生成される等価性によってテストも簡単になります。
// API request/response records
public record CreateProductRequest(
string Name,
decimal Price,
int Stock);
public record ProductResponse(
int Id,
string Name,
decimal Price,
int Stock,
DateTime CreatedAt);
// In controller:
app.MapPost("/products", (CreateProductRequest req, ProductService svc) =>
{
var product = svc.Create(req.Name, req.Price, req.Stock);
return Results.Created($"/products/{product.Id}",
new ProductResponse(product.Id, product.Name,
product.Price, product.Stock,
product.CreatedAt));
});単体テストでのレコードの等価性
値による等価性を持つレコードは、単体テストのアサーションに最適です。カスタム比較子を用意しなくても、== や Assert.Equal で期待値と実際のレコードを比較できます。
[Fact]
public async Task CreateOrder_ReturnsCorrectResponse()
{
var response = await _client.PostAsJsonAsync("/orders",
new CreateOrderRequest(CustomerId: 1, ProductId: 5, Quantity: 2));
var order = await response.Content.ReadFromJsonAsync<OrderResponse>();
// Simple equality check — no custom IEqualityComparer needed!
Assert.Equal(
new OrderResponse(Id: order!.Id, Status: "Pending", Total: 99.98m),
order);
}クイックチェック
C# のレコードは、既定でどのような等価性のセマンティクスを使用しますか。
まとめ: レコード型の基礎
重要なポイント:
- レコードは、既定で値による(構造的な)等価性を持つ参照型です
- 位置指定構文によって、コンストラクター、分解、等価性、ToString が生成されます
record struct(C# 10)は値型のバリエーションです- レコードは継承をサポートします。等価性には型の一致も必要です
- DTO、API 契約、単体テストのアサーションに最適です
- 位置指定パラメーターとともに、本体ブロックへ計算プロパティやメソッドを追加できます
よくある質問
「Record型:基礎と構文」レッスンは無料ですか?
はい。「Record型:基礎と構文」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C# Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C# Academyコースには全4レッスンが含まれています。
「Record型:基礎と構文」で何を学びますか?
record classとrecord structを宣言し、位置指定構文を理解して、recordとclassを比較します。 ブラウザで直接実行するハンズオンコードでC# Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
C# Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのC# Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。
「Record型:基礎と構文」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このC# Academyレッスンでコードを書いて実行できますか?
はい。すべてのC# Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- Record型:基礎と構文
- initとwithによる不変性
- 値の等価性と分解
- ドメイン駆動設計におけるRecord