什么时候泛型参数永远不会为空

时间:2012-09-17 11:08:01

标签: c# generics null resharper language-specifications

在通用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);

2 个答案:

答案 0 :(得分:5)

方法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] - 参数的分析。 http://youtrack.jetbrains.com/issue/RSRP-304111

中的类似代码存在此错误

答案 1 :(得分:4)

MSDN for IEqualityComparer<T>.GetHashCode Method说:

  

<强>例外:

     

ArgumentNullException obj的类型是引用类型,objnull

这似乎意味着使用GetHashCode<T>(T obj)参数调用null会违反IEqualityComparer<T>的合同。

我假设Resharper认为呼叫者遵守该合同,因此永远不会传入null