Enumerable.Sum()溢出 [英] Enumerable.Sum() overflowing
问题描述
嘿,我使用了 Enumerable.Sum()
的扩展方法从LINQ来计算哈希值codeS,和我有与<$ C $的问题C> OverflowExceptions 时,code变大。我试图把在选中
块中的电话,但似乎并没有帮助。
Hey, I'm using the Enumerable.Sum()
extension method from LINQ to compute hash codes, and am having a problem with OverflowExceptions
when the code gets big. I tried putting the call in an unchecked
block, but that didn't seem to help.
MSDN文档的方式说,如果该值变得太大就会抛出,但我在反射检查,这是所有有:
The MSDN documentation for the method says it will throw if the value gets too big, but I checked in reflector and this is all there is:
public static int Sum(this IEnumerable<int> source) {
if (source == null) {
throw Error.ArgumentNull("source");
}
int num = 0;
foreach (int num2 in source) {
num += num2;
}
return num;
}
根据这个反编译,我希望它或者溢出与否取决于调用code的范围内。为什么四溢,我怎样才能得到它停下来?
Based on this decompilation, I would expect it to either overflow or not depending on the context of the calling code. Why is it overflowing, and how can I get it to stop?
推荐答案
在code确实执行在C#检查
块。问题是,反射器是不正确的反编译检查
块,而不是将它们显示为正常工科大学生数学运算。您可以通过创建一个检查块,编译code,然后反编译它反射验证这一点吧。
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.
您也可以通过查看IL,而不是反编译的C#code验证这一点。取而代之的是加IL运code,你会看到,除了发生add.ovf。这是加的抛出对溢出的版本
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
- 切换到一个更大的类型,如
长
- 在写你自己的版本总和不使用检查除了
这篇关于Enumerable.Sum()溢出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!