何时可以泛型参数不能为空(When can a generic parameter never be

2019-09-22 12:15发布

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

Answer 1:

方法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



Answer 2:

MSDN为IEqualityComparer<T>.GetHashCode Method表示:

例外:

ArgumentNullException类型的obj为引用类型和objnull

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

我认为ReSharper的假设主叫方坚持该合同,因此从来没有在传球null



文章来源: When can a generic parameter never be null