checked和unchecked操作符用于整型算術(shù)運(yùn)算時(shí)控制當(dāng)前環(huán)境中的溢出檢查。下列運(yùn)算參與了checked和unchecked檢查(操作數(shù)均為整數(shù)):
1) 預(yù)定義的++和―― 一元運(yùn)算符。
2) 預(yù)定義的-一元運(yùn)算符。
3) 預(yù)定義的+、-、×、/等二元操作符。
4) 從一種整型到另一種整型的顯示數(shù)據(jù)轉(zhuǎn)換。
(一)使用checked
若運(yùn)算是常量表達(dá)式,則產(chǎn)生編譯錯(cuò)誤:The operation overflows at complie time in checked mode.
若運(yùn)算是非常量表達(dá)式,則運(yùn)行時(shí)會(huì)拋出一個(gè)溢出異常:OverFlowException異常。
checked 的用法可以是checked(//運(yùn)算代碼),也可以是checked{//運(yùn)算代碼},一般都是小量的代碼。
先看下面代碼:
Byte b = 100;
b += 200;
Console.WriteLine(b.ToString());
結(jié)果并不是我們預(yù)想的輸出300,輸出是44。假設(shè)我們用于計(jì)算那是多么的危險(xiǎn),上述代碼編譯時(shí)編譯器并沒有告訴程序員運(yùn)算溢出。而是偷偷的干了壞事...
下面我們加上checked,看效果如何:
byte b = 200;
checked
{
b += 200;
}
Console.WriteLine( b.ToString());
可以看到程序并沒有輸出,而是在運(yùn)行時(shí)拋出OverflowException,干了try catch的事情,告訴程序員說運(yùn)算溢出了,趕快修bug。在運(yùn)行時(shí)才拋出異常,在測試中帶來些許麻煩,那么如何在程序編譯時(shí)就拋出錯(cuò)誤呢,事實(shí)上編譯時(shí)是不能確定運(yùn)算結(jié)果的,也就是說運(yùn)算結(jié)果是在運(yùn)行是才能確定,所以只有在運(yùn)行時(shí)checked才做運(yùn)算溢出檢查。但是下列代碼是編譯不通過的(地球人都知道)
byte b;
checked
{
b = 256;
}
Console.WriteLine( b.ToString());
輸出錯(cuò)誤 Constant value '300' cannot be converted to a 'byte' ,byte的范圍是0~255嘛,編譯當(dāng)然報(bào)錯(cuò)。
需要指出的是,看下面代碼:
Byte b = 100;
b = (Byte)checked(b + 200);//不拋出System.OverflowException異常信息
這里解釋一下,因?yàn)?b+ 200 的結(jié)果是int32,checked是對int32的檢查當(dāng)然沒有運(yùn)算溢出,但是再將結(jié)果轉(zhuǎn)換成byte時(shí)沒有checked,所以返回值會(huì)被截掉不符合目標(biāo)類型的高位,輸出不正確的結(jié)果。
(二)使用unchecked
無論運(yùn)算是否是常量表達(dá)式,都沒有編譯錯(cuò)誤或是運(yùn)行時(shí)異常發(fā)生,只是返回值被截掉不符合目標(biāo)類型的高位,用法類似checked。
參考資料:
[1]C#中的checked、unchecked操作符http://www.knowsky.com/301786.html
[2]基元類型和Checked、UnChecked操作符的使用 http://www.cnblogs.com/noviceliu/archive/2009/03/11/1408461.html