使用 C# 泛型的错误装箱警告?

False boxing warning using C# Generics?

我正在尝试从 IEqualityComparer<T> 实现 Equals,如果 T 是引用类型,则返回 ReferenceEquals,如果 T 是值类型,则 Equals 返回。

所以我尝试这样做:

public bool Equals(T x, T y) {
    if (typeof(T).IsValueType)
        return Equals(x, y);

    return ReferenceEquals(x, y);
}

我的推理是,如果 xy 不是值类型,那么它们必须是引用类型,所以 ReferenceEquals 不应该装箱任何东西。

但是我收到这个警告:

装箱分配:值类型'T'到引用类型'object'

的转换

嗯,有一个拳套应用如果T不是class。由于这些方法最有可能调用 object(特别是 ReferenceEquals),因此调用这些方法需要一些装箱。 (顺便说一句,你现在正在递归调用 Equals。)

如果你使用 class 约束,警告将消失(但显然,它与你当前的 class 的可能性不完全匹配):

public class X<T> where T : class
{
    public bool Equals(T x, T y) {
        if (typeof(T).IsValueType)
            return Equals(x, y);

        return ReferenceEquals(x, y);
    }
}