在某些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;
}
答案 0 :(得分:5)
根据the documentation of IEqualityComparer<T>.GetHashCode
:
<强> ArgumentNullException 强>
obj
的类型是引用类型,obj
是 null 。
所以这是该界面合同的一部分,因此你应该关心。如果ArgumentNullException
为obj
,则执行此操作null
。
即使您怀疑或可以证明代码永远不会触及您不关心的部分,您也应始终遵守界面。稍后的更改可能会引入依赖于该行为的代码。