什么时候generics参数永远不会为空
在通用的GetHashCode(T foo)
方法中,我检查foo
是否为null
。 然而,我偶然发现了一个奇怪的Resharper警告。
在下面的代码中, foo
永远不会为null
吗?
private class FooComparer : IEqualityComparer 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(); int hash = fooComparer.GetHashCode(foo);
方法IEqualityComparer
的参数具有契约[NotNull]
,因为它具有在将null
作为参数提供时抛出exception的实现。
如果要直接使用FooComparer
并将null
作为其参数的exception安全,则可以按如下方式对其进行注释:
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]
参数的分析。 http://youtrack.jetbrains.com/issue/RSRP-304111中的类似代码存在此错误
IEqualityComparer
MSDN说:
例外:
ArgumentNullException
obj
的类型是引用类型,obj
是null
。
这似乎意味着使用null
参数调用GetHashCode
违反了IEqualityComparer
的约定。
我假设Resharper假定调用者遵守该契约,因此永远不会传入null
。