运算符 == 不能应用于 C# 中的泛型类型吗? [英] Can't operator == be applied to generic types in C#?

查看:33
本文介绍了运算符 == 不能应用于 C# 中的泛型类型吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据 == 运算符的文档>MSDN,

According to the documentation of the == operator in MSDN,

对于预定义的值类型,相等运算符 (==) 返回 true 如果其操作数的值相等,否则为假.对于参考类型除了字符串,== 返回真如果它的两个操作数指的是同一个目的.对于字符串类型,==比较字符串的值.用户定义的值类型可以重载== 运算符(请参阅运算符).所以可以用户定义的引用类型,虽然默认情况下 == 的行为与描述相同以上对于预定义和用户定义的引用类型.

For predefined value types, the equality operator (==) returns true if the values of its operands are equal, false otherwise. For reference types other than string, == returns true if its two operands refer to the same object. For the string type, == compares the values of the strings. User-defined value types can overload the == operator (see operator). So can user-defined reference types, although by default == behaves as described above for both predefined and user-defined reference types.

那么为什么这段代码无法编译?

So why does this code snippet fail to compile?

bool Compare<T>(T x, T y) { return x == y; }

我收到错误运算符=="不能应用于T"和T"类型的操作数.我想知道为什么,因为据我了解 == 运算符是为所有类型预定义的?

I get the error Operator '==' cannot be applied to operands of type 'T' and 'T'. I wonder why, since as far as I understand the == operator is predefined for all types?

谢谢大家.起初我没有注意到该声明仅与引用类型有关.我还认为为所有值类型提供了逐位比较,我现在知道这是正确的.

Thanks, everybody. I didn't notice at first that the statement was about reference types only. I also thought that bit-by-bit comparison is provided for all value types, which I now know is not correct.

但是,如果我使用引用类型,== 运算符会使用预定义的引用比较,还是会使用运算符的重载版本(如果类型定义了)?

But, in case I'm using a reference type, would the == operator use the predefined reference comparison, or would it use the overloaded version of the operator if a type defined one?

编辑 2:通过反复试验,我们了解到 == 运算符在使用不受限制的泛型类型时将使用预定义的引用比较.实际上,编译器将使用它可以找到的最佳方法来处理受限类型参数,但不会再寻找了.例如,下面的代码将始终打印 true,即使在调用 Test.test(new B(), new B()) 时:

Edit 2: Through trial and error, we learned that the == operator will use the predefined reference comparison when using an unrestricted generic type. Actually, the compiler will use the best method it can find for the restricted type argument, but will look no further. For example, the code below will always print true, even when Test.test<B>(new B(), new B()) is called:

class A { public static bool operator==(A x, A y) { return true; } }
class B : A { public static bool operator==(B x, B y) { return false; } }
class Test { void test<T>(T a, T b) where T : A { Console.WriteLine(a == b); } }

推荐答案

"...默认情况下 == 对于预定义和用户定义的引用类型的行为与上述相同."

"...by default == behaves as described above for both predefined and user-defined reference types."

类型 T 不一定是引用类型,因此编译器无法做出这种假设.

Type T is not necessarily a reference type, so the compiler can't make that assumption.

然而,这将编译,因为它更明确:

However, this will compile because it is more explicit:

    bool Compare<T>(T x, T y) where T : class
    {
        return x == y;
    }

跟进附加问题,但是,如果我使用引用类型,== 运算符会使用预定义的引用比较,还是会使用运算符的重载版本,如果类型定义一个?"

我本以为泛型上的 == 会使用重载版本,但下面的测试表明并非如此.有趣...我很想知道为什么!如果有人知道请分享.

I would have thought that == on the Generics would use the overloaded version, but the following test demonstrates otherwise. Interesting... I'd love to know why! If someone knows please share.

namespace TestProject
{
 class Program
 {
    static void Main(string[] args)
    {
        Test a = new Test();
        Test b = new Test();

        Console.WriteLine("Inline:");
        bool x = a == b;
        Console.WriteLine("Generic:");
        Compare<Test>(a, b);

    }


    static bool Compare<T>(T x, T y) where T : class
    {
        return x == y;
    }
 }

 class Test
 {
    public static bool operator ==(Test a, Test b)
    {
        Console.WriteLine("Overloaded == called");
        return a.Equals(b);
    }

    public static bool operator !=(Test a, Test b)
    {
        Console.WriteLine("Overloaded != called");
        return a.Equals(b);
    }
  }
}

输出

内联:重载 == 调用

Inline: Overloaded == called

通用:

按任意键继续...

跟进 2

我确实想指出将我的比较方法更改为

I do want to point out that changing my compare method to

    static bool Compare<T>(T x, T y) where T : Test
    {
        return x == y;
    }

导致调用重载的 == 运算符.我想如果没有指定类型(作为 where),编译器无法推断它应该使用重载运算符......尽管我认为它会有足够的信息来做出决定即使没有指定类型.

causes the overloaded == operator to be called. I guess without specifying the type (as a where), the compiler can't infer that it should use the overloaded operator... though I'd think that it would have enough information to make that decision even without specifying the type.

这篇关于运算符 == 不能应用于 C# 中的泛型类型吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆