【问题标题】:Why do I need to implement IComparable<T> to compare two values in generic method?为什么我需要实现 IComparable<T> 来比较泛型方法中的两个值?
【发布时间】:2014-08-12 08:27:28
【问题描述】:

我想知道为什么这样的代码不起作用:

public static bool cmp <T> (T a, T b)
{
    return a == b;
}

我假设应该添加一个IComparable 约束以使其工作(也许CompareTo 而不是==)。使用class 约束,将比较引用。使用struct 约束,不允许进行比较,也没有约束。

难道不能在传递对象时解析给定类型并比较引用,并在传递值类型时比较值吗?

【问题讨论】:

    标签: c# generics comparison


    【解决方案1】:

    language specification中有备注。

    看看第 7.10.6 段:

    预定义的引用类型相等运算符不允许比较值类型的操作数。因此,除非结构类型声明了自己的相等运算符,否则无法比较该结构类型的值。

    结构不能与== 进行比较,因为该运算符不是为每个值类型定义的。

    标准明确提到了整数类型、浮点数、小数、布尔值和枚举,当然还有引用类型。

    所以这是设计上不可能的。为什么?

    这是有道理的。直觉告诉我们,值类型应该按值进行比较。因此,如果两个值类型变量具有相同的内容,则它们是相等的。尽管结构是数据块,但它可能包含对对象的引用。如果这个引用不同,但具有相同的值,那么这种比较的结果应该是什么?

    例如:

    public struct A
    {
        public string S;
    }
    
    A a;
    A b;
    a.S = "Hello";
    b.S = "Hello world".Split(' ')[0]; //to avoid reusing the same reference, probably ;]
    var result = (a == b);
    

    答案应该是什么?二进制它们是不同的,但值是相同的。

    总是有ValueType.Equals,从object.Equals 重载,试图解决这个问题。它在可能的情况下执行值比较,在没有的情况下执行参考比较。但是你必须记住,它使结构有点臃肿。您对每个结构都有一个默认操作,这可能需要很长时间才能完成。所以这是可能的,但不是作为结构本身的功能。

    【讨论】:

    • 我可以想象,引用类型将通过它们的比较器进行比较,如果没有,则通过引用进行比较。此外,仅当它们属于相同类型时才会比较结构。我只是不确定我的思维方式是否与类型安全和静态语言方法相反。
    • 嗯,你有 T 作为泛型参数,所以它们是相同的类型。我正在扩展我的答案以提供更多理由。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-29
    • 2014-10-16
    • 1970-01-01
    • 1970-01-01
    • 2015-01-02
    • 2014-11-18
    相关资源
    最近更新 更多