GetHashCode()方法应该注意作为参数给出的null值吗?

时间:2013-04-11 12:11:16

标签: c# linq equals gethashcode

在某些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()方法中提供的空键,也不会在obj参数中使用GetHashCode()对象调用null。有人可以解释一下为什么吗? (它只是“纯粹的机会”,因为实现GroupBy()的方式和我给它的元素的顺序?)


编辑:

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

我已在ILSpy办理登机手续,GroupBy()已通过Lookup<TKey, TElement>

实施

这是一个重要的功能:

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

1 个答案:

答案 0 :(得分:5)

根据the documentation of IEqualityComparer<T>.GetHashCode

  

<强> ArgumentNullException
  obj的类型是引用类型,obj null

所以这是该界面合同的一部分,因此你应该关心。如果ArgumentNullExceptionobj,则执行此操作null

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