ภาพรวม
Struct (Structure) ใน C# เป็น Value Type (เก็บใน Stack) ใช้สำหรับจัดกลุ่มข้อมูลที่เกี่ยวข้องกัน (Related Data) หลายชนิดในตัวแปรเดียว คล้าย Class แต่แตกต่างที่เป็น Value Type ไม่ใช่ Reference Type
คีย์เวิร์ด struct
struct Books
{
public string title;
public string author;
public string subject;
public int book_id;
}ตัวอย่างโปรแกรม
using System;
struct Books
{
public string title;
public string author;
public string subject;
public int book_id;
}
public class TestStructure
{
public static void Main(string[] args)
{
Books book1; // ประกาศตัวแปร (ไม่ต้อง new)
Books book2;
// กำหนดค่า Book 1
book1.title = "C Programming";
book1.author = "Nuha Ali";
book1.subject = "C Programming Tutorial";
book1.book_id = 6495407;
// กำหนดค่า Book 2
book2.title = "Telecom Billing";
book2.author = "Zara Ali";
book2.subject = "Telecom Billing Tutorial";
book2.book_id = 6495700;
// แสดงข้อมูล
Console.WriteLine("Book 1 title : {0}", book1.title);
Console.WriteLine("Book 1 author : {0}", book1.author);
Console.WriteLine("Book 1 subject : {0}", book1.subject);
Console.WriteLine("Book 1 book_id : {0}", book1.book_id);
Console.WriteLine("Book 2 title : {0}", book2.title);
Console.WriteLine("Book 2 author : {0}", book2.author);
Console.WriteLine("Book 2 subject : {0}", book2.subject);
Console.WriteLine("Book 2 book_id : {0}", book2.book_id);
Console.ReadKey();
}
}ผลลัพธ์
Book 1 title : C Programming Book 1 author : Nuha Ali Book 1 subject : C Programming Tutorial Book 1 book_id : 6495407 Book 2 title : Telecom Billing Book 2 author : Zara Ali Book 2 subject : Telecom Billing Tutorial Book 2 book_id : 6495700
Struct vs Class - ความแตกต่างสำคัญ
| คุณสมบัติ | Struct (Value Type) | Class (Reference Type) |
|---|---|---|
| หน่วยความจำ | Stack (โดยทั่วไป) | Heap |
| การกำหนดค่า | Copy ค่าทั้งหมด (Deep Copy) | Copy Reference (Shallow) |
| Null | ไม่สามารถเป็น Null ได้ (Nullable<T> ได้) | สามารถเป็น Null ได้ |
| Inheritance | ไม่รองรับ (Implicit sealed) | รองรับ (Base/Derived) |
| Interface | Implement ได้ | Implement ได้ |
| Destructor | ไม่มี | มี (~ClassName) |
| Default Constructor | มีอยู่เสมอ (Zero-initialize) | มีถ้าไม่ประกาศ Constructor |
| Field Initializer | ไม่ได้ (Instance Field) | ได้ |
เมื่อไหร่ควรใช้ Struct
- ขนาดเล็ก (< 16 bytes / 4 fields ประมาณ)
- มีพฤติกรรมเหมือน Primitive Type (int, double, DateTime)
- Immutable (ค่าคงที่หลังสร้าง)
- ไม่ต้องการ Polymorphism/Inheritance
ตัวอย่าง Struct แบบสมัยใหม่ (C# 7.2+)
// Readonly Struct - Immutable โดยการออกแบบ
public readonly struct Point
{
public double X { get; }
public double Y { get; }
public Point(double x, double y)
{
X = x; Y = y;
}
// Expression-bodied members
public double DistanceFromOrigin => Math.Sqrt(X * X + Y * Y);
// Deconstructor
public void Deconstruct(out double x, out double y)
=> (x, y) = (X, Y);
// Override ToString
public override string ToString() => $"({X}, {Y})";
}
// ใช้งาน
var p = new Point(3, 4);
Console.WriteLine(p.DistanceFromOrigin); // 5
var (x, y) = p; // Deconstruct
ข้อสังเกตสำคัญ
- Struct ใหญ่ๆ การส่งผ่านเมธอด (Pass by Value) จะ Copy มาก → ใช้
in,ref,out,ref readonly - Boxing/Unboxing เกิดขึ้นเมื่อ Cast Struct เป็น Interface/Object
- Array ของ Struct: เก็บติดกันในหน่วยความจำ (Cache Friendly) - เร็วกว่า Array ของ Class
readonly struct(C# 7.2) บังคับ Immutable - ป้องกัน Bug- Built-in Types (
int,double,DateTime,Guid) เป็น Struct ทั้งหมด