Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C#

ความแตกต่างระหว่าง Class และ Struct ใน C#

Class = Reference Type, Struct = Value Type — ความแตกต่างพื้นฐานนี้นำไปสู่พฤติกรรมที่ต่างกันหลายประการ

Comparison Table

FeatureClass (Reference Type)Struct (Value Type)
Memory AllocationHeap (Managed by GC)Stack (หรือ Inline ใน Object อื่น)
AssignmentCopy Reference (Shallow)Copy Value (Deep)
NullabilityCan be NullCannot be Null (Nullable<T> ได้)
Inheritance✅ Full Support❌ No Inheritance (แต่ Implement Interface ได้)
Default ConstructorImplicit ParameterlessImplicit Parameterless (Zero-init), ไม่สามารถสร้าง Custom Parameterless ได้
Destructor/Finalizer✅ Supported❌ Not Supported
Field InitializersAllowedNot Allowed (Instance Fields)
Interface Implementation✅✅
Generic Constraintsclassstruct
Passing to MethodPass Reference (Pointer)Pass by Value (Copy) — ใช้ ref/in/out เพื่อ Pass by Reference

ตัวอย่าง: Assignment Behavior

// Class - Reference Semantics
class PointClass { public int X, Y; }
var c1 = new PointClass { X = 1, Y = 2 };
var c2 = c1; // Copy Reference
c2.X = 10;
Console.WriteLine(c1.X); // 10 — c1 เปลี่ยนไปด้วย!

// Struct - Value Semantics
struct PointStruct { public int X, Y; }
var s1 = new PointStruct { X = 1, Y = 2 };
var s2 = s1; // Copy Value
s2.X = 10;
Console.WriteLine(s1.X); // 1 — s1 ไม่เปลี่ยน!

เมื่อไหร่ใช้ Struct?

  • ขนาดเล็ก (< 16-24 bytes)
  • Immutable (Readonly Struct)
  • มี Lifetime สั้น (Short-lived)
  • ไม่ต้องการ Polymorphism
  • Performance Critical: Game Dev, Math, Graphics, High-frequency Trading
  • Examples: int, double, DateTime, Guid, Point, Vector, Color

เมื่อไหร่ใช้ Class?

  • ขนาดใหญ่ หรือ มี Reference Semantics
  • ต้องการ Inheritance / Polymorphism
  • Identity สำคัญ (Two Objects with Same Data ≠ Same Object)
  • Nullable โดย Nature
  • Long-lived Objects

Modern C#: readonly struct / record struct

// Immutable Struct (C# 7.2+)
public readonly struct Point3D {
    public double X { get; }
    public double Y { get; }
    public double Z { get; }
    
    public Point3D(double x, double y, double z) {
        X = x; Y = y; Z = z;
    }
}

// Record Struct (C# 10+) — Value-based Equality Built-in
public record struct Person(string Name, int Age);

⚠️ Common Pitfalls

  • ❌ Boxing: Struct → object / Interface → Allocation + Copy
  • ❌ Mutable Structs: ก่อให้เกิด Bugs ยากหา (Copy แล้ว Mutate ตัวไหนไม่ชัดเจน)
  • ❌ Large Structs: Copy Cost สูง — ใช้ Class หรือ Pass by Ref (ref/in)