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

Hug*_*une 4 c# generics resharper null language-specifications

在一个通用的GetHashCode(T foo)方法,我检查是否foonull.但是我偶然发现了一个奇怪的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
    }
}
Run Code Online (Sandbox Code Playgroud)

但据我所知,以下内容完全合法:

Foo foo = null;
var fooComparer = new FooComparer<Foo>();
int hash = fooComparer.GetHashCode(foo);
Run Code Online (Sandbox Code Playgroud)

Cod*_*aos 5

MSDN forIEqualityComparer<T>.GetHashCode Method 说:

例外:

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

这似乎暗示GetHashCode<T>(T obj)使用null参数调用违反了IEqualityComparer<T>.

我假设 Resharper 假设调用者遵守该合同,因此永远不会传入null.


小智 5

Method IEqualityComparer<T>.GetHashCode具有[NotNull]其参数的契约,因为它具有在null作为参数提供时抛出异常的实现.

如果要将FooComparer<T>.GetHashCodedirect和exception-safe null用作参数,可以按如下方式对其进行注释:

public int GetHashCode([JetBrains.Annotations.CanBeNull] T foo)
{
    // resharper warning:  "Expression is always false"
    if (Object.ReferenceEquals(null,foo)) return 0; 

    // ... calculate hash
}
Run Code Online (Sandbox Code Playgroud)

然而,[Not-Null]必须改进对参数的分析.http://youtrack.jetbrains.com/issue/RSRP-304111中的类似代码存在此错误