C# 为什么VS2017生成的GetHashCode没有未检查的块
我最近发现Visual Studio 2017可以为C# 为什么VS2017生成的GetHashCode没有未检查的块,c#,visual-studio,visual-studio-2017,gethashcode,C#,Visual Studio,Visual Studio 2017,Gethashcode,我最近发现Visual Studio 2017可以为Equals和GetHashCode自动生成覆盖,但我想知道为什么GetHashCode实现不在块中 我用两个公共字符串属性Foo和Bar创建了一个简单的类,生成的GetHashCode实现如下所示 public override int GetHashCode() { var hashCode=-504981047; hashCode=hashCode*-1521134295+EqualityComparer.Default.GetHashC
Equals
和GetHashCode
自动生成覆盖,但我想知道为什么GetHashCode
实现不在块中
我用两个公共字符串属性Foo和Bar创建了一个简单的类,生成的GetHashCode
实现如下所示
public override int GetHashCode()
{
var hashCode=-504981047;
hashCode=hashCode*-1521134295+EqualityComparer.Default.GetHashCode(Foo);
hashCode=hashCode*-1521134295+EqualityComparer.Default.GetHashCode(Bar);
返回哈希码;
}
我的印象是,
GetHashCode
实现的未检查非常重要,因为它很可能会溢出,我们不希望出现任何溢出异常,因为如果它结束的话就可以了。显然,我对无检查与未检查与检查的理解是有缺陷的。编写一些简单的测试来查看此应用程序中的溢出行为非常简单
简要总结如下:
如果在没有明确检查的情况下运行
- 如果编译器可以轻松且静态地确定代码将溢出,则会出现编译错误
- 如果运行时出现溢出,则不会引发任何溢出异常
- 编译器将允许明显溢出的代码
- 不会引发运行时溢出异常
- 如果编译器可以轻松且静态地确定代码将溢出,则会出现编译错误
- 如果运行时出现溢出,将抛出
系统.OverflowException
选中的
块中是非常重要的。如果您有可能溢出的代码,并且您不关心溢出,显然您可以跳过未检查的块(除非您的代码从静态分析的角度来看显然会溢出)
小提琴上的代码也被复制到这里供后人使用
使用系统;
公共课程
{
公共静态void Main()
{
var rand=new Random();
int检验=0;
//模糊到编译器无法“知道”该行将产生溢出
//未按选中的方式显式运行,因此不会引发运行时OverflowException
test=rand.Next(Int32.MaxValue-2,Int32.MaxValue)+10;
//非常简单,编译器“知道”该行将产生溢出
//编译错误(第16行,第10列):操作在编译时以检查模式溢出
//test=Int32.MaxValue+1;
//编译器允许“已知”的行溢出。
未经检查
{
test=Int32.MaxValue+1;
}
控制台写入线(测试);
//显式运行为未选中。仍然没有运行时溢出异常
未经检查
{
测试=测试-10;
}
控制台写入线(测试);
//显式以选中状态运行。System.OverflowException:算术运算导致溢出。
选中的
{
试验=试验+10;
}
控制台写入线(测试);
}
}
默认情况下,C#项目不检查溢出和下溢
右键单击项目,选择属性
,在底部的构建
选项卡上选择高级…
,选中标记为检查算术溢出/下溢的框
现在,默认行为是,如果显式未选中块中没有溢出,则抛出System.OverflowException
如果在项目启用溢出检查的情况下自动为Equals
和GetHashCode
生成覆盖,则未选中的块将如预期的那样存在
public override int GetHashCode()
{
未经检查
{
var hashCode=-504981047;
hashCode=hashCode*-1521134295+EqualityComparer.Default.GetHashCode(Foo);
hashCode=hashCode*-1521134295+EqualityComparer.Default.GetHashCode(Bar);
返回哈希码;
}
}
应该是这样,但遗憾的是,C项目模板没有打开溢出检查,所以他们没有考虑它。@ HSPASACT您的注释导致检查如何打开对C项目的溢出检查,如果对项目进行了溢出检查,则将GethHAc码的重写放在未选中的块中。这相当聪明。如果你决定以后再打开它,那就太糟糕了。@HansPassant如果它总是处于未检查的块中,就更好了。