2008-10-26 69 views
12

當您嘗試在C#.NET中聲明一個值超出其值範圍的無符號變量時,它將被標記爲編譯器錯誤,但如果您在運行時產生負值並將其分配給在運行時變量值包裝。兩個'uint'的差異

uint z = -1; // Will not compile 

uint a = 5; 
uint b = 6; 
uint c = a - b; // Will result in uint.MaxValue 

有沒有很好的理由爲什麼無符號變量在這種情況下換行而不是拋出異常?

謝謝。

+0

ulong同樣適用 – Llyle 2008-10-26 21:29:31

回答

26

在C#中聲明一個未分配的變量不會被標記爲錯誤 - 嘗試將一個無效值賦給變量是。舉例來說,這裏的未明確賦值的變量(假設它是本地的)聲明之後:

uint z; 

-1不是一個UINT任何超過0.5是一個有效的價值,這就是爲什麼你的例子止跌不會編譯。

現在,至於其餘的:整數類型只是在溢出包裝 - 就像加1到int.MaxValue返回int.MinValue。與程序檢查每個操作是否溢出相比,這是一個顯着的性能改進 - 代價是可能不會發現錯誤。

只有當您處於未經檢查的環境中時,請注意 - 如果您在檢查的環境中執行了任何這些操作,您將會得到異常。例如;

class Test 
{ 
    static void Main() 
    { 
     checked 
     { 
      uint a = 5; 
      uint b = 6; 
      uint c = a - b; 
     } 
    } 
} 

運行這一點,你會看到一個OverflowException拋出。如果這是你想要什麼,你的整個項目,你可以將其設置在項目屬性(或與/checked+命令行選項來csc編譯。)

編輯:值得注意的是,其他的答案表明,你可以把檢查的上下文中的代碼量更少 - 只需聲明和分配c甚至只是計算。這非常靈活。

+0

達姆 - 打了它...我打「郵政」,發現你已經得到了+5 ... [刪除...] – 2008-10-26 21:38:48

+0

這是一個可怕的快速選票。它不像它一直坐着...... – 2008-10-26 21:39:36

+1

令人驚訝的是,我從來沒有遇到過檢查和未檢查的上下文。這很棒。 – Llyle 2008-10-26 21:41:36

7

包裝是因爲通過默認C#未選中。如果添加一個「檢查」塊,溢出將被檢測到:

uint a = 3, b = 4; 
    checked 
    { 
     uint c = a - b; // throws an overflow 
    } 

至於編譯器:它只是要求有效的數據。

3

這只是默認值 - 您可以更改編譯設置以啓用運行時漫遊溢出檢查。如果你打開它,異常將會像你期待的那樣拋出。或者,您可以通過將其置於檢查塊中來開啓檢查特定操作的功能。

uint c = checked(a - b); 
0

可能是值得澄清這裏uint無符號 INT,不是未分配 INT。巨大差距!

-2

它包裝爲負值的原因是因爲用於整數算術的Two's Complement數學。

簡短的答案是最重要的位用作符號。零是積極的;一個是消極的。

-1

始終使用雙。性能差異不大,而且更加靈活和適應。這種做法可以防止異常並縮短開發時間。肛門的人討厭它。