Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么VS2017生成的GetHashCode没有未检查的块_C#_Visual Studio_Visual Studio 2017_Gethashcode - Fatal编程技术网

C# 为什么VS2017生成的GetHashCode没有未检查的块

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

我最近发现Visual Studio 2017可以为
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如果它总是处于未检查的块中,就更好了。