รูปแบบออบเจ็กต์ที่เปลี่ยนแปลงไม่ได้
ออกแบบออบเจ็กต์ที่ไม่เปลี่ยนแปลงหลังการสร้าง
รูปแบบออบเจ็กต์ที่เปลี่ยนแปลงไม่ได้ เป็นบทเรียน C# Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C# Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน
การออกแบบออบเจ็กต์ที่ไม่เปลี่ยนแปลง
ออบเจ็กต์ที่ไม่เปลี่ยนแปลงจะไม่เปลี่ยนแปลงอีกหลังจากสร้างเสร็จ ความไม่เปลี่ยนแปลงช่วยกำจัดข้อผิดพลาดจำนวนมากที่เกี่ยวข้องกับสถานะที่เปลี่ยนแปลงได้ร่วมกัน และทำให้ออบเจ็กต์ปลอดภัยเมื่อต้องส่งต่อหรือเก็บไว้ในแคช
พร็อพเพอร์ตีที่อ่านได้อย่างเดียว
พร็อพเพอร์ตีที่ไม่เปลี่ยนแปลงซึ่งเรียบง่ายที่สุดคือพร็อพเพอร์ตีที่อ่านได้อย่างเดียวและกำหนดค่าเพียงครั้งเดียวจากตัวสร้าง
using System;
class Point {
public int X { get; }
public int Y { get; }
public Point(int x, int y) { X = x; Y = y; }
}
var p = new Point(3, 4);
Console.WriteLine(p.X + "," + p.Y); // 3,4ใช้ init กับไวยากรณ์ตัวเริ่มต้น
ใช้พร็อพเพอร์ตี init เมื่อคุณต้องการความไม่เปลี่ยนแปลงพร้อมไวยากรณ์ตัวเริ่มต้นออบเจ็กต์ที่สะดวก
using System;
class Color {
public int R { get; init; }
public int G { get; init; }
public int B { get; init; }
}
var c = new Color { R = 255, G = 128, B = 0 };
Console.WriteLine(c.R + "," + c.G + "," + c.B); // 255,128,0ใช้ required กับฟิลด์ที่จำเป็น
ใช้ required + init ร่วมกัน เพื่อไม่ให้ลืมกำหนดฟิลด์ที่สำคัญ และไม่ให้ฟิลด์เหล่านั้นเปลี่ยนแปลงได้
using System;
class Money {
public required decimal Amount { get; init; }
public required string Currency { get; init; }
}
var m = new Money { Amount = 9.99m, Currency = "USD" };
Console.WriteLine(m.Amount + " " + m.Currency); // 9.99 USDส่งคืนออบเจ็กต์ใหม่แทนการเปลี่ยนแปลงออบเจ็กต์เดิม
ชนิดที่ไม่เปลี่ยนแปลงจะแสดงการดำเนินการที่ดูเหมือนเป็นการ "เปลี่ยนแปลง" ในรูปแบบเมธอดที่ส่งคืนอินสแตนซ์ใหม่ โดยไม่แตะต้องออบเจ็กต์เดิม
using System;
class Point {
public int X { get; init; }
public int Y { get; init; }
public Point Move(int dx, int dy) => new Point { X = X + dx, Y = Y + dy };
}
var a = new Point { X = 1, Y = 1 };
var b = a.Move(2, 3);
Console.WriteLine(a.X + "," + a.Y + " -> " + b.X + "," + b.Y); // 1,1 -> 3,4คอลเลกชันที่ไม่เปลี่ยนแปลง
สำหรับฟิลด์ที่เป็นคอลเลกชัน ให้จัดเก็บคอลเลกชันที่ไม่เปลี่ยนแปลงหรืออ่านได้อย่างเดียว เพื่อไม่ให้เนื้อหาถูกเปลี่ยนแปลงผ่านออบเจ็กต์
using System;
using System.Collections.Immutable;
class Team {
public ImmutableList<string> Members { get; init; } = ImmutableList<string>.Empty;
}
var t = new Team { Members = ["Ada", "Lin"] };
var t2 = new Team { Members = t.Members.Add("Sam") };
Console.WriteLine(t.Members.Count + " " + t2.Members.Count); // 2 3การคัดลอกเพื่อป้องกันการเปลี่ยนแปลง
หากจำเป็นต้องรับคอลเลกชันที่เปลี่ยนแปลงได้ ให้คัดลอกคอลเลกชันนั้นเมื่อรับเข้ามา เพื่อไม่ให้การเปลี่ยนแปลงจากภายนอกส่งผลเข้ามาได้
using System;
using System.Collections.Generic;
using System.Linq;
class Snapshot {
private readonly int[] data;
public Snapshot(IEnumerable<int> source) => data = source.ToArray();
public IReadOnlyList<int> Data => data;
}
var list = new List<int> { 1, 2, 3 };
var snap = new Snapshot(list);
list.Add(4); // does not affect snap
Console.WriteLine(snap.Data.Count); // 3ความเท่าเทียมกันตามค่า
ออบเจ็กต์ที่ไม่เปลี่ยนแปลงมักต้องการความเท่าเทียมกันตามค่า กล่าวคือ อินสแตนซ์สองรายการที่มีข้อมูลเหมือนกันจะถือว่าเท่ากัน เรคคอร์ดมีความสามารถนี้ให้โดยอัตโนมัติ ส่วนคลาสต้องเขียนทับการทำงานเอง
using System;
record Coord(int X, int Y);
Console.WriteLine(new Coord(1, 2) == new Coord(1, 2)); // Trueความปลอดภัยสำหรับเธรดโดยไม่ต้องทำอะไรเพิ่ม
เนื่องจากออบเจ็กต์ที่ไม่เปลี่ยนแปลงจะไม่เปลี่ยนค่า ออบเจ็กต์เหล่านี้จึงปลอดภัยสำหรับเธรดโดยธรรมชาติเมื่อต้องใช้งานร่วมกันโดยไม่ใช้ล็อก
using System;
class ReadonlyConfig {
public required string Env { get; init; }
}
var cfg = new ReadonlyConfig { Env = "prod" };
// safe to read from many threads without synchronization
Console.WriteLine(cfg.Env); // prodฟิลด์ readonly และโครงสร้าง
ใช้ฟิลด์ readonly และ readonly struct เพื่อบังคับให้ชนิดค่าไม่เปลี่ยนแปลงในระดับฟิลด์
using System;
readonly struct Vector {
public readonly double X, Y;
public Vector(double x, double y) { X = x; Y = y; }
public double Length => Math.Sqrt(X * X + Y * Y);
}
Console.WriteLine(new Vector(3, 4).Length); // 5นำทุกอย่างมาประกอบกัน
ชนิดที่ไม่เปลี่ยนแปลงอย่างสมบูรณ์ ซึ่งผสาน required, init, ความเท่าเทียมกันตามค่า และเมธอดสำหรับอัปเดตโดยไม่เปลี่ยนแปลงออบเจ็กต์เดิม
using System;
record Account(string Id, decimal Balance) {
public Account Deposit(decimal amount) => this with { Balance = Balance + amount };
}
var a = new Account("A1", 100m);
var b = a.Deposit(50m);
Console.WriteLine(a.Balance + " -> " + b.Balance); // 100 -> 150ตรวจสอบอย่างรวดเร็ว
ยืนยันหลักการอัปเดตโดยไม่เปลี่ยนแปลงออบเจ็กต์เดิม
สรุปทบทวน
คุณได้เรียนรู้รูปแบบการสร้างออบเจ็กต์ที่ไม่เปลี่ยนแปลง
- ใช้พร็อพเพอร์ตีที่อ่านได้อย่างเดียวหรือพร็อพเพอร์ตี
initและใช้requiredกับข้อมูลที่จำเป็น - จำลองการเปลี่ยนแปลงด้วยเมธอดที่ส่งคืนอินสแตนซ์ใหม่
- จัดเก็บคอลเลกชันที่ไม่เปลี่ยนแปลงหรือคอลเลกชันที่คัดลอกเพื่อป้องกันการเปลี่ยนแปลง
- เรคคอร์ดมีความเท่าเทียมกันตามค่าและการคัดลอกด้วย
withให้โดยอัตโนมัติ ส่วนความไม่เปลี่ยนแปลงช่วยให้ปลอดภัยสำหรับเธรด
คำถามที่พบบ่อย
บทเรียน “รูปแบบออบเจ็กต์ที่เปลี่ยนแปลงไม่ได้” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “รูปแบบออบเจ็กต์ที่เปลี่ยนแปลงไม่ได้” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C# Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “รูปแบบออบเจ็กต์ที่เปลี่ยนแปลงไม่ได้”
ออกแบบออบเจ็กต์ที่ไม่เปลี่ยนแปลงหลังการสร้าง คุณปฏิบัติ C# Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C# Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน C# Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “รูปแบบออบเจ็กต์ที่เปลี่ยนแปลงไม่ได้” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน C# Academy นี้ได้ไหม
ได้ บทเรียน C# Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- ตัวกำหนดค่าแบบ init เท่านั้น
- ตัวปรับแต่ง required
- รูปแบบออบเจ็กต์ที่เปลี่ยนแปลงไม่ได้
- นิพจน์ with บนเรคคอร์ด