2012-11-16 54 views
2

MSDN examples只是編譯時錯誤。僅僅爲了解決編譯時錯誤而未經檢查?

這只是我看到@JonSkeet在這裏使用它的答案:https://stackoverflow.com/a/263416/360211,我不明白爲什麼如果它只是編譯時。

static void Main() 
    { 
     const int x = 4; 
     int y = int.MaxValue; 
     int z = x*y; 
     Console.WriteLine(z); 
     Console.ReadLine(); 
    } 

主要生產-4,與此相同:

static void Main() 
    { 
     unchecked 
     { 
      const int x = 4; 
      const int y = int.MaxValue; 
      int z = x*y; // without unchecked, this is compile error 
      Console.WriteLine(z); 
      Console.ReadLine(); 
     } 
    } 

這將引發運行時:

static void Main() 
    { 
     checked 
     { 
      const int x = 4; 
      int y = int.MaxValue; 
      int z = x*y; //run time error, can checked be set system wide? 
      Console.WriteLine(z); 
      Console.ReadLine(); 
     } 
    } 

所以喬恩這樣做,因爲它可以廣集系統,編譯器標誌或以其他方式?

+0

您的'y'是未檢查代碼中的'const',而不是已檢查的代碼中,如果它是檢查代碼中的'const',會扔comp迴旋時間錯誤。 – Bobson

+0

@Bobson是故意顯示不同之處。 – weston

+0

用於改善我的哈希代碼生成器助手類http://stackoverflow.com/a/10634833/360211 – weston

回答

1

當實際計算值時,是否執行操作是否在checkedunchecked塊中。當相乘/添加兩個變量時,這幾乎總是在運行時,因爲它們在編譯時不知道。

在你的例子中,兩個變量都是常量;這意味着編譯時文字之間的計算結果可以在編譯時完成(它是)。由於結果是在編譯時計算的,並且不在unchecked塊中,因此無法計算結果而沒有錯誤。那不是表示選中/未選中的塊通常是編譯時檢查;他們很少。

是的,可以更改整個代碼庫是否處於checked/unchecked上下文中的項目屬性。如果你正在編寫一個庫,這個方法也可以在上下文中調用。因此,如果有一個代碼塊必須在已選中或未選中的情況下運行,添加此類塊是一種很好的做法,即使您當前的項目設置對於該方法是正確的。另外,如果沒有其他的東西,它會讓未來的讀者更清楚地意識到這個片段,「這種方法依賴於整數溢出」,vs「這種方法絕對不能溢出。「

+0

由於「...可能的方法從任何上下文中調用」給你,所以它更多而不僅僅是一個項目範圍內的考慮問題。 – weston

1

絕對不是。如果操作溢出,它確定在執行時間是否拋出異常(OverflowException

例如,在Noda Time中,我們執行了幾乎所有的檢查上下文中的算術(它是項目的默認值)。但是,對於散列碼,我們總是使用unchecked塊,因爲散列碼計算溢出絕對沒問題 - 值的大小並不重要;溢出不會影響正確性。

它只在編譯時與操作有關,編譯器可以知道知道會由於涉及常量值而溢出。

有關更多詳細信息,請參閱C#4規範的第7.6.12節。

0

通過去設置既不checkedunchecked代碼的默認行爲:

項目屬性 - >建設 - >高級 - >檢查算術溢出/下溢

默認爲新項目已關閉,這就是爲什麼我假設unchecked沒有運行時間效應。

相關問題