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

sizeof Operator ใน C# - หาขนาดชนิดข้อมูล

ออปเปอเรเตอร์ 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
bool1true/false
byte / sbyte10-255 / -128-127
short / ushort2±32,767 / 0-65,535
int / uint4±2.1B / 0-4.2B
long / ulong8±9.2E18 / 0-1.8E19
float4±1.5E-45 to ±3.4E38
double8±5.0E-324 to ±1.7E308
decimal16±1.0E-28 to ±7.9E28
char2UTF-16 Code Unit
IntPtr / UIntPtr4 (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)