簡體   English   中英

為什么VS 2017生成沒有未經檢查的塊的GetHashCode

[英]Why does VS 2017 generate GetHashCode without an unchecked block

我最近發現Visual Studio 2017可以自動生成EqualsGetHashCode替代,但是我想知道為什么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

如果在為項目打開溢出檢查的情況下自動生成EqualsGetHashCode替代,則未檢查的塊將按預期存在

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM