ชนิด Record: พื้นฐานและไวยากรณ์
ประกาศคลาส record และ struct record ทำความเข้าใจไวยากรณ์แบบระบุตำแหน่ง และเปรียบเทียบ records กับ classes
ชนิด Record: พื้นฐานและไวยากรณ์ เป็นบทเรียน C# Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C# Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน
ชนิดเรคคอร์ดคืออะไร
เรคคอร์ด ซึ่งเปิดตัวใน C# 9 เป็นชนิดอ้างอิงที่ออกแบบมาสำหรับ ข้อมูลที่ไม่เปลี่ยนแปลงและมีความหมายเชิงค่า โดยจะสร้างการเปรียบเทียบความเท่ากันตามค่าของคุณสมบัติ เมธอด ToString() ที่อ่านเข้าใจง่าย และรองรับการเปลี่ยนแปลงแบบไม่ทำลายข้อมูลผ่านนิพจน์ with โดยอัตโนมัติ
ไวยากรณ์เรคคอร์ดแบบระบุตำแหน่ง
ไวยากรณ์แบบระบุตำแหน่งเป็นรูปแบบที่กระชับที่สุด คุณสมบัติ ตัวสร้าง การแยกโครงสร้าง และการเปรียบเทียบความเท่ากันจะถูกสร้างขึ้นจากบรรทัดเดียว
// 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() };
}การสืบทอดด้วยเรคคอร์ด
เรคคอร์ดรองรับการสืบทอด เรคคอร์ดที่สืบทอดสามารถเพิ่มคุณสมบัติและเข้าร่วมในกฎการเปรียบเทียบความเท่ากันเดียวกัน โดยเรคคอร์ดสองรายการจะเท่ากันก็ต่อเมื่อชนิดและค่าทั้งหมดตรงกัน
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 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) เป็นรูปแบบชนิดค่า- เรคคอร์ดรองรับการสืบทอด โดยชนิดต้องตรงกันด้วยจึงจะเท่ากัน
- เหมาะอย่างยิ่งสำหรับออบเจ็กต์ถ่ายโอนข้อมูล สัญญาของส่วนติดต่อโปรแกรม และการตรวจสอบในแบบทดสอบหน่วย
- เพิ่มคุณสมบัติที่คำนวณได้และเมธอดในบล็อกบอดีควบคู่กับพารามิเตอร์แบบระบุตำแหน่งได้
คำถามที่พบบ่อย
บทเรียน “ชนิด Record: พื้นฐานและไวยากรณ์” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ชนิด Record: พื้นฐานและไวยากรณ์” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C# Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “ชนิด Record: พื้นฐานและไวยากรณ์”
ประกาศคลาส record และ struct record ทำความเข้าใจไวยากรณ์แบบระบุตำแหน่ง และเปรียบเทียบ records กับ classes คุณปฏิบัติ C# Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C# Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน C# Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน
บทเรียน “ชนิด Record: พื้นฐานและไวยากรณ์” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน C# Academy นี้ได้ไหม
ได้ บทเรียน C# Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- ชนิด Record: พื้นฐานและไวยากรณ์
- ความไม่เปลี่ยนแปลงด้วย init และ with
- ความเท่ากันของค่าและการแยกโครงสร้าง
- Records ในการออกแบบที่ขับเคลื่อนด้วยโดเมน