首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# unsafe 不安全代碼入門:指標運算、fixed 關鍵字、編譯選項與實戰範例

     編輯:關於C#

為什麼需要 unsafe?

.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; // 回寫
        }
    }
}

進階:Span<T> 替代 unsafe(.NET Core 2.1+)


// 同樣零邊界檢查、可指標運算,但型別安全、無需 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);

⚠️ 風險與最佳實踐

  1. 記憶體安全:指標越界、釘住過久導致 GC 壓力、stackalloc 爆堆疊。
  2. 除錯困難:Visual Studio 對 unsafe 區塊支援有限,建議封裝於獨立方法並加單元測試。
  3. 優先使用 Span/Memory:現代 .NET 提供安全的高效能替代方案,僅在互通非託管 API、極致效能調優時才用 unsafe。
  4. 簽署組件:unsafe 組件需完整信任,無法在沙箱環境(如舊版 Silverlight、部分雲函數)執行。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved