0Pricing
C# Academy · บทเรียน

รูปแบบออบเจ็กต์ที่เปลี่ยนแปลงไม่ได้

ออกแบบออบเจ็กต์ที่ไม่เปลี่ยนแปลงหลังการสร้าง

รูปแบบออบเจ็กต์ที่เปลี่ยนแปลงไม่ได้ เป็นบทเรียน 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. ตัวกำหนดค่าแบบ init เท่านั้น
  2. ตัวปรับแต่ง required
  3. รูปแบบออบเจ็กต์ที่เปลี่ยนแปลงไม่ได้
  4. นิพจน์ with บนเรคคอร์ด
← กลับไปที่ C# Academy