这是我的简单代码:
T a;
T b;
if (a == b)
// sth.
else
// sth. else
当我尝试编译时,我收到一条错误消息,指出==
运算符对泛型类型无效。所以我必须使用object.Equals()
方法。
==
运算符实际上是否实际调用Equals
的{{1}}方法?为什么我可以使用两种泛型类型的object
方法而不是Equals
运算符?
答案 0 :(得分:8)
operator ==
必须在结构中重载才能使用,因此完全不受约束的类型参数不能使用它。您可以将函数约束为class
以允许默认参考比较:
public void Foo<T>() where T : class {
T a = default(T);
T b = a;
if(a == b)
System.Diagnostics.Debug.WriteLine("");
else
System.Diagnostics.Debug.WriteLine("");
}
上述代码有效,因为默认情况下,引用类型可以与operator ==
一起使用:
对于字符串以外的引用类型, 如果两个操作数引用同一个对象,则==返回true。
这就是if (new object() == new object()) {}
编译的原因,即使System.Object
没有超载operator ==
。
答案 1 :(得分:2)
==运算符没有定义T的所有可能值[感谢Daniel](或者你可能放在T上的任何约束,我假设),所以你不能使用它。您只能调用T上的运算符,方法和属性,可以在由T表示的所有可能类型上调用。
在许多情况下,operator ==调用'Equals',但这并不意味着它们是相同的。
答案 2 :(得分:1)
==
令牌用于表示C#中的两个不同运算符。只有当操作数的类型适合“相等检查”运算符的特定定义重载时,它们中的第一个才适用。第二个测试引用相等,仅当一个操作数是null
,一个操作数是类类型,另一个是该类型的实例可以实现的接口,两个都是接口,两个都是相同的类类型,或者适用时两者都是类类型,一类是另一类的超类型。除非将泛型约束为定义了相等检查重载的类型,否则第一种形式将不能用于泛型;第二种形式限于已知满足特定的一种指定条件的参考类型。注意,在某些情况下,第二个运算符可以用于第一个运算符的位置,例如, bool IsSame<T>(T p1, T p2) where T:class { return p1==p2; }
将使用引用比较比较String
类型的两个变量,即使为==
定义了String
的重载。发生这种情况的原因是T
已知不足以应用String
的{{1}}重载,但已知==
的两个操作数都是相同的引用类型。< / p>
值得注意的是,其他一些语言对C#使用==
执行的两个操作使用不同的令牌。例如,VB.NET使用==
进行相等比较,使用=
进行引用相等。