在一个通用GetHashCode(T foo)
的方法,我检查是否foo
是null
。 不过,我只是偶然发现了一个奇怪的ReSharper的警告。
在下面的代码,可以foo
永远是null
?
private class FooComparer<T> : IEqualityComparer<T> where T: Foo
{
public int GetHashCode(T foo)
{
// resharper warning: "Expression is always false"
if (Object.ReferenceEquals(null,foo)) return 0;
// ... calculate hash
}
}
但是据我所知,以下是完全合法的:
Foo foo = null;
var fooComparer = new FooComparer<Foo>();
int hash = fooComparer.GetHashCode(foo);
方法IEqualityComparer<T>.GetHashCode
具有合同[NotNull]
为其参数,因为它具有抛出异常时实现null
作为参数被提供。
如果你想使用FooComparer<T>.GetHashCode
直接和异常安全的null
作为其参数,可以按如下标注为:
public int GetHashCode([JetBrains.Annotations.CanBeNull] T foo)
{
// resharper warning: "Expression is always false"
if (Object.ReferenceEquals(null,foo)) return 0;
// ... calculate hash
}
不过分析[Not-Null]
α参数必须加以改进。 这个bug存在类似代码http://youtrack.jetbrains.com/issue/RSRP-304111
MSDN为IEqualityComparer<T>.GetHashCode Method
表示:
例外:
ArgumentNullException
类型的obj
为引用类型和obj
是null
。
这似乎意味着,调用GetHashCode<T>(T obj)
与null
参数违反合同IEqualityComparer<T>
我认为ReSharper的假设主叫方坚持该合同,因此从来没有在传球null
。