已核取和未核取的語句 (C# 參考)
checked
和 unchecked
陳述式會指定整數型別算術運算和轉換的溢位檢查內容。 發生整數算術溢位時,溢位檢查內容會定義會發生什麼情況。 在 checked 內容中,會擲出 System.OverflowException;如果常數運算式發生溢位,則會發生編譯時間錯誤。 在 unchecked 內容中,會捨棄目的型別不適用的高序位位元,以便將作業結果截斷。 例如,加法會將最大值換行至最小值。 下列範例顯示已核取和未核取內容中的相同作業:
uint a = uint.MaxValue;
unchecked
{
Console.WriteLine(a + 3); // output: 2
}
try
{
checked
{
Console.WriteLine(a + 3);
}
}
catch (OverflowException e)
{
Console.WriteLine(e.Message); // output: Arithmetic operation resulted in an overflow.
}
注意
用戶定義運算子和轉換的溢位行為可能會與上一段中所述的行為不同。 特別是,使用者定義的已檢查運算子可能不會在核取的內容中擲回例外狀況。
如需詳細資訊,請參閱算術運算子一文的算術溢位和除以零,以及使用者定義檢查運算子一節。
若要指定運算式的溢位檢查內容,您也可以使用 checked
和 unchecked
運算子,如下列範例所示:
double a = double.MaxValue;
int b = unchecked((int)a);
Console.WriteLine(b); // output: -2147483648
try
{
b = checked((int)a);
}
catch (OverflowException e)
{
Console.WriteLine(e.Message); // output: Arithmetic operation resulted in an overflow.
}
checked
和 unchecked
陳述式和運算子只會影響陳述式區塊或運算子括弧內的這些作業溢位檢查內容,如下列範例所示:
int Multiply(int a, int b) => a * b;
int factor = 2;
try
{
checked
{
Console.WriteLine(Multiply(factor, int.MaxValue)); // output: -2
}
}
catch (OverflowException e)
{
Console.WriteLine(e.Message);
}
try
{
checked
{
Console.WriteLine(Multiply(factor, factor * int.MaxValue));
}
}
catch (OverflowException e)
{
Console.WriteLine(e.Message); // output: Arithmetic operation resulted in an overflow.
}
在上述範例中,Multiply
本機函式的第一個叫用會顯示 checked
陳述式不會影響 Multiply
函式內的溢位檢查內容,因為不會擲回例外狀況。 在 Multiply
函式的第二個調用中,計算函式第二個引數的運算式會在核取的內容中進行評估,並產生例外狀況,因為在 checked
陳述式區塊內。
和 unchecked
的行為checked
取決於類型和作業。 即使是整數,作業也一 unchecked(x / 0)
律會擲回,因為沒有明智的行為。 檢查類型和作業的行為,以瞭解和 unchecked
關鍵詞如何影響checked
您的程序代碼。
數值類型和溢位檢查內容
checked
和 unchecked
關鍵詞主要適用於有合理溢位行為的整數型別。 在兩者的補碼值中,變成 T.MinValue
的包裝行為T.MaxValue + 1
是明智的。 表示的值不正確,因為它無法放入型別的記憶體中。 因此,位代表完整結果的下層 n 位。
對於 、、 double
和 Half
等decimal
float
類型,代表更複雜的值或一個補碼值,包裝並不合理。 它無法用來計算更大或更精確的結果,因此 unchecked
並無好處。
float
、 double
和 Half
具有和 的合理飽和值PositiveInfinity
NegativeInfinity
,因此您可以在內容中unchecked
偵測溢位。 針對 decimal
,不存在這類限制,而 飽和 MaxValue
可能會導致錯誤或混淆。 在和 unchecked
內容中使用 decimal
checked
擲回的作業。
受溢位檢查內容影響的作業
溢位檢查內容會影響下列作業:
下列內建算術運算子:一元
++
、--
、-
和二進位+
、-
、*
和/
運算子,其運算元屬於整數類型 (亦即整數數值或 char 類型) 或是 列舉類型。整數型別之間的明確數值轉換,或從
float
或double
轉換為整數型別。注意
當您將
decimal
值轉換成整數型別,且結果超出目的地類型的範圍時,不論溢位檢查內容為何,一律會擲回 OverflowException。從 C# 11 開始,使用者定義的已檢查運算子和轉換。 如需詳細資訊,請參閱算術運算子一文中的使用者定義的已檢查運算一節。
預設溢位檢查內容
如果您未指定溢位檢查內容,CheckForOverflowUnderflow 編譯程式選項的值會定義非常數表達式的默認內容。 根據預設,該選項的值是 unset ,且整數類型算術運算和轉換會在 unchecked 的內容中執行。
常數表達式預設會在核取的內容中進行評估,而溢位會導致編譯時期錯誤。 您可以使用 unchecked
陳述式或運算子,明確指定常數運算式的 unchecked 內容。
C# 語言規格
如需詳細資訊,請參閱 C# 語言規格的下列幾節: