首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >林格求和OverflowException?

林格求和OverflowException?
EN

Stack Overflow用户
提问于 2012-06-14 13:10:50
回答 3查看 7.9K关注 0票数 11

我为EventLogEntry实现了一个自定义的EventLogEntry。

代码语言:javascript
复制
public class EventLogEntryListComparison :
    IEqualityComparer<List<EventLogEntry>>,
    IEqualityComparer<EventLogEntry>

对于IEqualityComparer<List<EventLogEntry>>,GetHashCode函数非常简单。

代码语言:javascript
复制
public int GetHashCode(List<EventLogEntry> obj)
{
    return obj.Sum(entry => 23 * GetHashCode(entry));
}

但是,这会为某些条目抛出一个OverflowException。

代码语言:javascript
复制
"Arithmetic operation resulted in an overflow."
   at System.Linq.Enumerable.Sum(IEnumerable`1 source)
   at System.Linq.Enumerable.Sum[TSource](IEnumerable`1 source, Func`2 selector)
   at <snip>.Diagnostics.EventLogAnalysis.EventLogEntryListComparison.GetHashCode(List`1 obj) in C:\dev\<snip>Diagnostics.EventLogAnalysis\EventLogEntryListComparison.cs:line 112
   at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
   at System.Collections.Generic.Dictionary`2.set_Item(TKey key, TValue value)
   at <snip>.Diagnostics.EventLogAnalysis.Program.AnalyseMachine(String validMachineName) in C:\dev\<snip>.Diagnostics.EventLogAnalysis\Program.cs:line 104
   at System.Threading.Tasks.Parallel.<>c__DisplayClass2d`2.<ForEachWorker>b__23(Int32 i)
   at System.Threading.Tasks.Parallel.<>c__DisplayClassf`1.<ForWorker>b__c()

在调试过程中尝试获得相同的错误,但在立即窗口中无法获得相同的错误后,我将代码更改为“再见”OverflowException?

代码语言:javascript
复制
int total = 0;
foreach (var eventLogEntry in obj)
{
    total += GetHashCode(eventLogEntry);
}

return total;

LINQ的求和函数是如何表现不同的?

编辑2

由于一些注释,修正后的GetHashCode函数现在如下所示,

代码语言:javascript
复制
public int GetHashCode(List<EventLogEntry> obj)
{
    return unchecked(obj.Aggregate(17,
        (accumulate, entry) =>
        accumulate * 23 + GetHashCode(entry)));
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-06-14 13:15:33

LINQ的Enumerable.Sum(...)方法在checked块中执行添加。这意味着,如果总和溢出,他们会故意抛出异常。

您的和不在checked块中,所以它是否抛出异常取决于.无论是从checked块内部调用它,还是在程序集上调用它,我都相信。

票数 9
EN

Stack Overflow用户

发布于 2012-06-14 13:16:57

这是因为在C#中编译的程序集的不同行为以及Enumerable.Sum的实现。

如果您在C#中编译程序集,默认情况下所有的添加都是在unchecked模式下执行的,这就是为什么在最后一个示例中没有溢出的原因。如果您希望运行时抛出溢出,您需要使用checked块(当然,对于您的散列,您不想这样做,所以C#的默认行为是可以的)。

相反,Enumerable.Sum是用来计算和的,通常您不希望和溢出。这就是为什么Enumerable.Sumchecked模式下执行其计算,如果和溢出,则会引发异常。

票数 5
EN

Stack Overflow用户

发布于 2012-06-14 13:41:24

如果您正在计算哈希代码,您可能不想使用求和。使用Xor (^)将提供相同的结果,甚至可能会将您的哈希代码扩展到比和更多的地方。试试这个方法:

代码语言:javascript
复制
public int GetHashCode(List<EventLogEntry> obj)
{
    int total = 0;
    foreach (var eventLogEntry in obj)
    {
        total ^= GetHashCode(eventLogEntry);
    }

    return total;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11033777

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档