4

在一些 C# 代码中,我使用linq GroupBy<TSource, TKey>()带有自定义IEqualityComparer<T>.

GroupBy(x => x.SomeField, new FooComparer());

我用作分组键的字段可以是null. 因此,我不得不null在方法中添加一些检查Equals()

public bool Equals(Foo x, Foo y)
{
    if (x == null && y == null)
       return true;
    else if (x == null && y != null)
       return false;
    else if (x != null && y == null)
       return false;
    else 
       return x.Id == y.Id;
}

问题是:我应该在GetHashCode()功能上做同样的事情吗?

public int GetHashCode(Foo obj)
{
    if (obj == null)          //is this really needed ?
       return default(int);   //
    else
       return obj.Id;
}

我不明白的东西:即使GroupBy()方法中提供了空键,GetHashCode()也永远不会用nullobj 参数中的对象调用。有人可以解释一下为什么吗?(这只是“纯粹的机会”,因为GroupBy()实施方式和我给它的元素的顺序吗?)


编辑 :

正如caerolus指出的那样,在GroupBy()实施过程中进行了一些特殊检查。

我签入ILSpyGroupBy()实施了Lookup<TKey, TElement>

这是相关的功能:

internal int InternalGetHashCode(TKey key)
{
    if (key != null)
    {
        return this.comparer.GetHashCode(key) & 2147483647;
    }
    return 0;
}
4

1 回答 1

5

根据以下文件IEqualityComparer<T>.GetHashCode

ArgumentNullException
的类型obj 是引用类型并且objnull

所以这是该接口合同的一部分,因此您应该关心。通过抛出ArgumentNullExceptionif objis 来实现它null

即使您怀疑或可以证明代码永远不会触及您不关心的部分,您也应该始终遵守界面。稍后的更改可能会引入依赖于该行为的代码。

于 2013-04-11T12:24:01.563 回答