checked和unchecked操作符用於整型算術運算時控制當前環境中的溢出檢查。下列運算參與了checked和unchecked檢查(操作數均爲整數):
1) 預定義的++和――一元運算符。
2) 預定義的-一元運算符。
3) 預定義的+、-、×、/等二元操作符。
4) 從一種整型到另一種整型的顯示數據轉換。
當上述整型運算產生一個目標類型無法表示的大數時,可以有相應的處理方式:
(一)使用checked
若運算是常量表達式,則產生編譯錯誤:The operation overflows at complie time in checked mode.
若運算是非常量表達式,則運行時會拋出一個溢出異常:OverFlowException異常
(二)使用unchecked
無論運算是否是常量表達式,都沒有編譯錯誤或是運行時異常發生,只是返回值被截掉不符合目標類型的高位。
(三)既未使用checked又未使用unchecked
若運算是常量表達式,默認情況下總是進行溢出檢查,同使用checked一樣,會無法通過編譯。
若運算是非常量表達式,則是否進行溢出檢查,取決於外部因素,包括編譯器狀態、執行環境參數等。
下例說明了checked和unchecked操作符的使用方法:
class Test
{
static int x = 1000000;
static int y = 1000000;
static int F()
{
return checked(x*y); //運行時拋出OverFlowException異常
}
static int G()
{
return unchecked(x*y); //截去高位部分,返回-727379968
}
static int H()
{
return x*y; //依賴於編譯器的默認設置,一般是不檢查
}
}
========================================================================
lock 關鍵字將語句塊標記爲臨界區,方法是獲取給定對象的互斥鎖,執行語句,然後釋放該鎖。此語句的形式如下:
Object thisLock = new Object(); lock (thisLock) { // Critical code section }
//在 C# 中使用線程的簡單示例。
// statements_lock.cs using System; using System.Threading; class ThreadTest { public void RunMe() { Console.WriteLine("RunMe called"); } static void Main() { ThreadTest b = new ThreadTest(); Thread t = new Thread(b.RunMe); t.Start(); } }
//使用線程和 lock。只要 lock 語句存在,語句塊就是臨界區並且 balance 永遠不會是負數。
// statements_lock2.cs using System; using System.Threading; class Account { private Object thisLock = new Object(); int balance; Random r = new Random(); public Account(int initial) { balance = initial; } int Withdraw(int amount) { // This condition will never be true unless the lock statement // is commented out: if (balance < 0) { throw new Exception("Negative Balance"); } // Comment out the next line to see the effect of leaving out // the lock keyword: lock(thisLock) { if (balance >= amount) { Console.WriteLine("Balance before Withdrawal : " + balance); Console.WriteLine("Amount to Withdraw : -" + amount); balance = balance - amount; Console.WriteLine("Balance after Withdrawal : " + balance); return amount; } else { return 0; // transaction rejected } } } public void DoTransactions() { for (int i = 0; i < 100; i++) { Withdraw(r.Next(1, 100)); } } } class Test { static void Main() { Thread[] threads = new Thread[10]; Account acc = new Account(1000); for (int i = 0; i < 10; i++) { Thread t = new Thread(new ThreadStart(acc.DoTransactions)); threads[i] = t; } for (int i = 0; i < 10; i++) { threads[i].Start(); } } }