Enumerable.Sum() overflowing

前端 未结 3 1936
不思量自难忘°
不思量自难忘° 2021-01-04 08:06

Hey, I\'m using the Enumerable.Sum() extension method from LINQ to compute hash codes, and am having a problem with OverflowExceptions when the cod

相关标签:
3条回答
  • 2021-01-04 08:40

    checked only applies to expressions in the current block, not any (already-compiled) called method. To use unchecked maths, you'll need to implement your own version of Sum inside an unchecked block

    0 讨论(0)
  • 2021-01-04 08:41

    I wrote this function for generic enumerables. I'd love to hear any remarks about it.

    public static int SequenceHashCode<T>(IEnumerable<T> seq)
    {
        unchecked
        {
            return seq != null ? seq.Aggregate(0, (sum,obj) => sum+obj.GetHashCode()) : 0;
        }
    }
    
    0 讨论(0)
  • 2021-01-04 08:55

    The code is indeed executing in a C# checked block. The problem is that reflector doesn't properly decompile checked blocks and instead shows them as normal mathmatical operations. You can verify this yourself by creating a checked block, compiling the code and then decompiling it in reflector.

    You can also verify this by looking at the IL instead of the decompiled C# code. Instead of the add IL opcode you'll see that the addition occurs with add.ovf. This is the version of add that throws on overflows

    L_001a: callvirt instance !0 [mscorlib]System.Collections.Generic.IEnumerator`1<int32>::get_Current()
    L_001f: stloc.1 
    L_0020: ldloc.0 
    L_0021: ldloc.1 
    L_0022: add.ovf <-- This is an overflow aware addition
    L_0023: stloc.0 
    L_0024: ldloc.2 
    

    There is no way to get this particular method to not throw on overflow. Your best options are the following

    1. Switch to a larger type such as long
    2. Write your own version of Sum which does not use checked addition
    0 讨论(0)
提交回复
热议问题