การใช้ Pointer ใน C# (Unsafe Code)
Pointer เป็นตัวแปรที่เก็บที่อยู่หน่วยความจำของตัวแปรอีกตัวหนึ่ง C# รองรับ pointer ในบริบท unsafe เท่านั้น ต้อง compile ด้วย flag /unsafe
ตัวอย่าง: ดึงค่าผ่าน Pointer
using System;
namespace UnsafeCodeApplication
{
class Program
{
public static void Main()
{
unsafe
{
int var = 100;
int* p = &var; // Address-of operator
Console.WriteLine($"Data (var): {var}");
Console.WriteLine($"Data (*p): {*p}"); // Dereference
Console.WriteLine($"Address (p): {(long)p}"); // Address as number
Console.WriteLine($"Address (&var): {(long)&var}");
}
Console.ReadKey();
}
}
}
ผลลัพธ์ (ตัวอย่าง)
Data (var): 100
Data (*p): 100
Address (p): 77678547
Address (&var): 77678547
คำสั่งสำคัญของ Pointer
| Operator | ชื่อ | คำอธิบาย |
|---|---|---|
& | Address-of | lấyที่อยู่ของตัวแปร |
* | Dereference | เข้าถึงค่าที่ address ชี้ไป |
-> | Member access | เข้าถึงสมาชิกผ่าน pointer (p->Field) |
[] | Indexer | p[i] เทียบเท่า *(p + i) |
การคอมไพล์ Unsafe Code
// .NET CLI
dotnet build -p:AllowUnsafeBlocks=true
// หรือใน .csproj
true
// Visual Studio: Project Properties → Build → Allow unsafe code
กรณีใช้งาน Pointer ใน C#
- Interop กับ C/C++ DLL (P/Invoke)
- Image processing / Pixel manipulation (ประสิทธิภาพสูง)
- High-performance computing (HPC)
- Network packet parsing
- Memory-mapped files
Span<T> และ Memory<T> - ทางเลือกปลอดภัยกว่า (C# 7.2+)
// แทน pointer ใช้ Span
int[] arr = { 1, 2, 3, 4, 5 };
Span span = arr.AsSpan(1, 3); // ดูเฉพาะ [2,3,4] ไม่ copy
// stackalloc - จองหน่วยความจำบน stack (ไม่ต้อง GC)
Span buffer = stackalloc byte[256];
ข้อควรระวัง
- Pointer ทำลาย Type Safety และ Memory Safety ของ .NET
- GC ไม่ย้ายหน่วยความจำที่ pointer ชี้อยู่ (pinned) - ใช้
fixedkeyword - อาจก่อให้เกิด Security Vulnerabilities
- ไม่ทำงานบาง Platform (WASM, บาง iOS)
- หลีกเลี่ยงใช้เว้นแต่จำเป็นจริงๆ
Fixed Statement - ป้องกัน GC ย้าย Memory
unsafe
{
int[] arr = { 1, 2, 3 };
fixed (int* p = &arr[0]) // Pin array ในหน่วยความจำ
{
// ใช้ p ได้อย่างปลอดภัย
} // Unpin อัตโนมัติเมื่อออก scope
}