ออปเปอเรเตอร์ sizeof ใน C# ใช้คืนค่าขนาด (ในหน่วย **Byte**) ของ **Unmanaged Type** (Value Type ที่ไม่มี Reference Fields) ใช้ได้ใน **Unsafe Context** เท่านั้น (ยกเว้น Built-in Types บางตัว)
Syntax
sizeof(type)
Built-in Types ที่ใช้ sizeof ได้โดยไม่ต้อง unsafe
| Type |
Size (Bytes) |
Range |
bool | 1 | true/false |
byte / sbyte | 1 | 0-255 / -128-127 |
short / ushort | 2 | ±32,767 / 0-65,535 |
int / uint | 4 | ±2.1B / 0-4.2B |
long / ulong | 8 | ±9.2E18 / 0-1.8E19 |
float | 4 | ±1.5E-45 to ±3.4E38 |
double | 8 | ±5.0E-324 to ±1.7E308 |
decimal | 16 | ±1.0E-28 to ±7.9E28 |
char | 2 | UTF-16 Code Unit |
IntPtr / UIntPtr | 4 (32-bit) / 8 (64-bit) | Platform-dependent |
ตัวอย่างโค้ด
using System;
namespace Demo {
class Program {
static void Main(string[] args) {
Console.WriteLine("The size of bool is {0}", sizeof(bool)); // 1
Console.WriteLine("The size of char is {0}", sizeof(char)); // 2
Console.WriteLine("The size of short is {0}", sizeof(short)); // 2
Console.WriteLine("The size of int is {0}", sizeof(int)); // 4
Console.WriteLine("The size of long is {0}", sizeof(long)); // 8
Console.WriteLine("The size of float is {0}", sizeof(float)); // 4
Console.WriteLine("The size of double is {0}", sizeof(double)); // 8
Console.WriteLine("The size of decimal is {0}", sizeof(decimal)); // 16
Console.WriteLine("The size of IntPtr is {0}", sizeof(IntPtr)); // 4 or 8
Console.ReadLine();
}
}
}
ผลลัพธ์ (64-bit Process)
The size of bool is 1
The size of char is 2
The size of short is 2
The size of int is 4
The size of long is 8
The size of float is 4
The size of double is 8
The size of decimal is 16
The size of IntPtr is 8
sizeof กับ Custom Struct (ต้อง Unsafe)
// Struct ไม่มี Reference Fields = Unmanaged Type
struct Point {
public int X;
public int Y;
}
struct Node {
public int Id;
public Node Next; // Reference Field! ไม่ใช่ Unmanaged Type
}
// ใน Unsafe Context
unsafe {
Console.WriteLine(sizeof(Point)); // 8 (4 + 4)
// Console.WriteLine(sizeof(Node)); // Compile Error: Not unmanaged type
}
Unmanaged Type Constraint (C# 7.3+)
// Generic Method ที่รับเฉพาะ Unmanaged Types
public static int SizeOf() where T : unmanaged {
return sizeof(T);
}
// ใช้งาน
int size = SizeOf(); // 8
// int size2 = SizeOf(); // Compile Error: Node ไม่ใช่ unmanaged
การใช้งานจริง (Use Cases)
1. Memory Layout / Struct Layout
[StructLayout(LayoutKind.Sequential)]
struct Vertex {
public Vector3 Position; // 12 bytes
public Vector2 TexCoord; // 8 bytes
public Color Color; // 4 bytes (ถ้า struct 4 bytes)
// Total: 24 bytes (aligned)
}
unsafe {
int vertexSize = sizeof(Vertex); // 24
}
2. Buffer / Memory Operations
unsafe {
int count = 1000;
int size = sizeof(float) * count; // 4000 bytes
// Stackalloc - จัดสรรบน Stack
float* buffer = stackalloc float[count];
// หรือ Heap
byte[] managedBuffer = new byte[size];
}
3. Interop / P/Invoke
[StructLayout(LayoutKind.Sequential)]
struct NativeRect {
public int Left, Top, Right, Bottom;
}
// Marshal.SizeOf ใช้ได้กับ Managed Types ด้วย (แต่ช้ากว่า)
int size1 = sizeof(NativeRect); // Unsafe, Fast, Compile-time
int size2 = Marshal.SizeOf(); // Safe, Runtime, รองรับทุก Struct
sizeof vs Marshal.SizeOf
| ด้าน |
sizeof |
Marshal.SizeOf |
| Context |
Unsafe (Compile-time) |
Safe (Runtime) |
| Supported Types |
Unmanaged Types Only |
All Blittable Types |
| Performance |
Constant (Compile-time) |
Runtime Lookup |
| Layout Awareness |
Respects StructLayout |
Respects StructLayout |
⚠️ ข้อจำกัด
- ไม่ใช้กับ Reference Types (
class, string, array, delegate)
- ไม่ใช้กับ Struct ที่มี Reference Fields
- ต้อง Compile ด้วย
/unsafe (ยกเว้น Built-in Types)
- ค่าที่ได้เป็น **Compile-time Constant** (Constant Expression)