![](/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.