![](/img/trans.png)
[英]Why does overriding GetHashCode() block INotifyPropertyChanged?
[英]Why does VS 2017 generate GetHashCode without an unchecked block
我最近發現Visual Studio 2017可以自動生成Equals
和GetHashCode
替代,但是我想知道為什么GetHashCode
實現不在未檢查的塊中?
我用兩個公共字符串屬性Foo和Bar創建了一個簡單的類,生成的GetHashCode
實現如下所示。
public override int GetHashCode()
{
var hashCode = -504981047;
hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(Foo);
hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(Bar);
return hashCode;
}
我的印象是,未經檢查的GetHashCode
實現很重要,因為它很可能會溢出,並且我們不希望有任何溢出異常,因為它可以環繞起來就很好。
默認情況下,C#項目不檢查溢出和下溢。
右鍵單擊項目,選擇“ Properties
,在底部的“ Build
選項卡上,選擇“ Advanced...
,選中標記為“ Check for arithmetic overflow/underflow
的框
現在,如果顯式unchecked
塊中沒有溢出,則默認行為是拋出System.OverflowException
。
如果在為項目打開溢出檢查的情況下自動生成Equals
和GetHashCode
替代,則未檢查的塊將按預期存在
public override int GetHashCode()
{
unchecked
{
var hashCode = -504981047;
hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(Foo);
hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(Bar);
return hashCode;
}
}
顯然,我對無檢查與未檢查與已檢查的理解存在缺陷。 編寫一些簡單的測試以查看此小提琴中的溢出行為非常簡單。
快速摘要是這樣的:
如果沒有顯式檢查運行
如果運行時未選中
如果運行明確檢查
System.OverflowException
。 所以...我想從所有這些中學到的教訓是,如果您有一些可能會溢出的計算,並且您擔心溢出,那么將其放在checked
塊中非常重要。 如果您有可能溢出的代碼,而又不關心溢出,則顯然可以跳過未檢查的塊(除非從靜態分析的角度來看,代碼顯然會溢出)。
小提琴的代碼也復制到這里,以供后代使用。
using System;
public class Program
{
public static void Main()
{
var rand = new Random();
int test = 0;
//obscured enough that the compiler doesn't "know" that the line will produce an overflow
//Does not run explicitly as checked, so no runtime OverflowException is thrown
test = rand.Next(Int32.MaxValue-2, Int32.MaxValue) + 10;
//simple enough that the compiler "knows" that the line will produce an overflow
//Compilation error (line 16, col 10): The operation overflows at compile time in checked mode
//test = Int32.MaxValue + 1;
//Explicitly running as unchecked. Compiler allows line that is "known" to overflow.
unchecked
{
test = Int32.MaxValue + 1;
}
Console.WriteLine(test);
//Explicitly running as unchecked. Still no runtime OverflowException
unchecked
{
test = test - 10;
}
Console.WriteLine(test);
//Explicitly running as checked. System.OverflowException: Arithmetic operation resulted in an overflow.
checked
{
test = test + 10;
}
Console.WriteLine(test);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.