我为EventLogEntry实现了一个自定义的EventLogEntry。
public class EventLogEntryListComparison :
IEqualityComparer<List<EventLogEntry>>,
IEqualityComparer<EventLogEntry>对于IEqualityComparer<List<EventLogEntry>>,GetHashCode函数非常简单。
public int GetHashCode(List<EventLogEntry> obj)
{
return obj.Sum(entry => 23 * GetHashCode(entry));
}但是,这会为某些条目抛出一个OverflowException。
"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?
int total = 0;
foreach (var eventLogEntry in obj)
{
total += GetHashCode(eventLogEntry);
}
return total;LINQ的求和函数是如何表现不同的?
编辑2
由于一些注释,修正后的GetHashCode函数现在如下所示,
public int GetHashCode(List<EventLogEntry> obj)
{
return unchecked(obj.Aggregate(17,
(accumulate, entry) =>
accumulate * 23 + GetHashCode(entry)));
}发布于 2012-06-14 13:15:33
LINQ的Enumerable.Sum(...)方法在checked块中执行添加。这意味着,如果总和溢出,他们会故意抛出异常。
您的和不在checked块中,所以它是否抛出异常取决于.无论是从checked块内部调用它,还是在程序集上调用它,我都相信。
发布于 2012-06-14 13:16:57
这是因为在C#中编译的程序集的不同行为以及Enumerable.Sum的实现。
如果您在C#中编译程序集,默认情况下所有的添加都是在unchecked模式下执行的,这就是为什么在最后一个示例中没有溢出的原因。如果您希望运行时抛出溢出,您需要使用checked块(当然,对于您的散列,您不想这样做,所以C#的默认行为是可以的)。
相反,Enumerable.Sum是用来计算和的,通常您不希望和溢出。这就是为什么Enumerable.Sum在checked模式下执行其计算,如果和溢出,则会引发异常。
发布于 2012-06-14 13:41:24
如果您正在计算哈希代码,您可能不想使用求和。使用Xor (^)将提供相同的结果,甚至可能会将您的哈希代码扩展到比和更多的地方。试试这个方法:
public int GetHashCode(List<EventLogEntry> obj)
{
int total = 0;
foreach (var eventLogEntry in obj)
{
total ^= GetHashCode(eventLogEntry);
}
return total;
}https://stackoverflow.com/questions/11033777
复制相似问题