根据MSDN中==
运营商的文档,
对于预定义的值类型,相等运算符(==)如果其操作数的值相等,则返回true,否则返回false。对于字符串以外的引用类型,如果==的两个操作数引用同一对象,则==返回true。对于字符串类型,==比较字符串的值。用户定义的值类型可能会使==运算符重载(请参阅运算符)。用户定义的引用类型也可以,尽管 默认情况下==的行为与上述预定义和用户定义的引用类型相同。
那么,为什么此代码片段无法编译?
bool Compare<T>(T x, T y) { return x == y; }
我收到错误运算符'=='不能应用于类型'T'和'T'的操作数。我不知道为什么,因为据我所知,该==
操作符是为所有类型预定义的?
编辑:谢谢大家。起初我没有注意到该声明仅与引用类型有关。我还认为为所有值类型提供了逐位比较,现在我知道这是不正确的。
但是,如果我使用的是引用类型,==
操作员会使用预定义的引用比较吗?如果定义了一个类型,它会使用操作员的重载版本吗?
编辑2:通过反复试验,我们了解到,==
当使用无限制的泛型类型时,运算符将使用预定义的引用比较。实际上,编译器将使用它可以为受限类型参数找到的最佳方法,但是不再赘述。例如,true
即使Test.test<B>(new B(), new B())
被调用,下面的代码也将始终print :
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); } }
==
相同类型的两个操作数之间也不允许某些类型的类型可能是有用的。对于struct
不重载的类型(“预定义”类型除外),这是正确的operator ==
。作为一个简单的示例,请尝试以下操作:var map = typeof(string).GetInterfaceMap(typeof(ICloneable)); Console.WriteLine(map == map); /* compile-time error */
var kvp1 = new KeyValuePair<int, int>(); var kvp2 = kvp1;
,您将无法检查,kvp1 == kvp2
因为它KeyValuePair<,>
是一个结构,它不是C#的预定义类型,并且不会重载operator ==
。举一个var li = new List<int>(); var e1 = li.GetEnumerator(); var e2 = e1;
无法使用的示例e1 == e2
(这里有一个嵌套结构List<>.Enumerator
("List`1+Enumerator[T]"
由运行时调用),它不会重载==
)。
bool
void