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

C# checked 與 unchecked 運算子深度解析:溢位檢測控制、常數與非常數差異、方法邊界限制

     編輯:關於C#

運算子 vs 陳述式:兩種形式

受影響運算

  • 一元:++, --, - (負號) —— 整數運算元
  • 二元:+, -, *, / —— 兩運算元皆為整數
  • 顯式轉換:(byte)largeInt, (int)largeLong

不受影響:浮點數 (float/double)、decimal (內建檢查)、邏輯/位運算、位移。

常數運算式 vs 非常數運算式:關鍵差異

形式語法適用範圍
運算子 (運算式)checked(expr), unchecked(expr)單一運算式
陳述式 (區塊)checked { ... }, unchecked { ... }多行陳述式區塊

const int MAX = int.MaxValue;

// 常數運算式
int c1 = MAX + 1;               // CS0220 編譯錯誤
int c2 = checked(MAX + 1);      // CS0220 編譯錯誤
int c3 = unchecked(MAX + 1);    // 通過,c3 = -2147483648

// 非常數運算式
int v = GetRuntimeValue();
int r1 = v + 1;                  // 預設截斷
int r2 = checked(v + 1);         // 可能拋出 OverflowException
int r3 = unchecked(v + 1);       // 截斷

方法邊界限制:checked 不跨越方法呼叫


int Multiply(int x, int y) => x * y; // 方法內無 checked

// 呼叫端加 checked 無效!
int result = checked(Multiply(1000000, 1000000)); // 不拋出,Multiply 內部 unchecked

// 正確做法 1:方法內部加 checked
int MultiplySafe(int x, int y) { checked { return x * y; } }

// 正確做法 2:回傳前檢查
int MultiplyCheck(int x, int y) {
    if (x != 0 && y > int.MaxValue / x) throw new OverflowException();
    return x * y;
}

專案層級預設控制

  • Visual Studio:專案屬性 → Build → "Check for arithmetic overflow/underflow" (/checked+)
  • .csproj:<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
  • 預設 unchecked (效能優先)

階乘範例:逐步檢測


long Factorial(int n)
{
    long result = 1;
    for (int i = 2; i <= n; i++)
    {
        checked { result *= i; } // 每步檢測
    }
    return result;
}

// 測試
try { Console.WriteLine(Factorial(25)); } // 25! > long.MaxValue
catch (OverflowException) { Console.WriteLine("溢位發生於 25!"); }

最佳實踐決策表

類型預設 (無關鍵字)checked 內文unchecked 內文
常數運算式 (編譯期可計算)編譯錯誤 (CS0220)編譯錯誤允許,結果截斷
非常數運算式 (執行期計算)依專案設定 (預設 unchecked:截斷)執行期拋出 OverflowException截斷,不拋出

decimal 內建溢位檢查


decimal d = decimal.MaxValue;
d = d + 1; // 無需 checked,直接拋出 OverflowException

decimal 專為金融設計,永遠檢查溢位,無法關閉。

總結

checked/unchecked 提供靈活的整數溢位控制:運算式/區塊兩種形式、常數/非常數不同語意、不跨越方法邊界。關鍵決策:金融/關鍵計算用 checked、位元/雜湊用 unchecked、效能熱路徑手動檢查。decimal 內建檢查無需額外關鍵字。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
場景建議理由
金融計算、索引運算、緩衝區大小區塊 checked正確性優先,溢位即 Bug
雜湊、加密、隨機數、位元操作unchecked 明確標記語意明確:預期回繞行為
高效能熱路徑手動檢查 if (a > MAX - b)避免例外開銷,分支預測友善
庫開發文件化行為,不強制專案設定讓消費者自行決定
常數運算式依賴編譯期檢測零成本捕捉 Bug