.NET 預設型別安全,禁止指標運算。但在高效能影像處理、互通非託管 DLL、記憶體映射檔等場景,指標能避免陣列邊界檢查、減少複製、直接操作記憶體,效能提升數倍。
// 專案屬性 → Build → Allow unsafe code
// 或 csc /unsafe Program.cs
unsafe static void DoubleValue(int* p) => *p *= 2;
unsafe static void Main()
{
int val = 5;
DoubleValue(&val);
Console.WriteLine(val); // 10
}
| 關鍵字 | 用途 |
|---|---|
unsafe | 標記型別/成員/區塊允許指標 |
fixed | 釘住 managed 陣列/字串,防止 GC 移動 |
stackalloc | 在堆疊分配記憶體,自動釋放,無 GC 壓力 |
sizeof | 取得非 managed 型別大小(需 unsafe) |
void* | 通用指標,類似 C void* |
unsafe void ToGrayscale(byte[] rgb, int width, int height)
{
fixed (byte* p = rgb)
{
byte* ptr = p;
for (int i = 0; i < width * height; i++)
{
byte b = *ptr++; byte g = *ptr++; byte r = *ptr++;
byte gray = (byte)(0.299 * r + 0.587 * g + 0.114 * b);
ptr[-3] = ptr[-2] = ptr[-1] = gray; // 回寫
}
}
}
// 同樣零邊界檢查、可指標運算,但型別安全、無需 unsafe 區塊
void ToGrayscaleSafe(Span rgb, int width, int height)
{
for (int i = 0; i < width * height; i++)
{
int offset = i * 3;
byte gray = (byte)(0.299 * rgb[offset+2] + 0.587 * rgb[offset+1] + 0.114 * rgb[offset]);
rgb[offset] = rgb[offset+1] = rgb[offset+2] = gray;
}
}
// 呼叫端:ToGrayscaleSafe(rgbArray.AsSpan(), w, h);