5

在一个通用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
    }
}

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

Foo foo = null;
var fooComparer = new FooComparer<Foo>();
int hash = fooComparer.GetHashCode(foo);
4

2 回答 2

5

方法IEqualityComparer<T>.GetHashCode具有其参数的合同,因为它具有在作为参数提供[NotNull]时引发异常的实现。null

如果你想FooComparer<T>.GetHashCode直接使用异常安全的 fornull作为它的参数,你可以注释如下:

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中的类似代码存在此错误

于 2012-09-17T14:43:13.047 回答
5

MSDNIEqualityComparer<T>.GetHashCode Method 说:

例外:

ArgumentNullException的类型obj是引用类型并且objnull

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

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

于 2012-09-17T11:15:31.353 回答