Why two generic types cannot be compared with '=='?
Here is my simple code:
T a;
T b;
if (a == b)
// sth.
else
// sth. e开发者_开发技巧lse
When I try to compile, I get an error saying the ==
operator is invalid for generic types. So I have to use the object.Equals()
method.
Doesn't the ==
operator actually call the Equals
method of object
? Why can I use the Equals
method of two generic types but not the ==
operator?
operator ==
must be overloaded in structs in order to be used, hence a completely unconstrained type parameters cannot use it. You can constrain the function to class
to allow default reference comparison:
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("");
}
The above code works because by default, reference types can be used with operator ==
:
For reference types other than string, == returns true if its two operands refer to the same object.
This is why if (new object() == new object()) {}
compiles, even though System.Object
doesn't overload operator ==
.
The == operator is not defined all possible values of T [thanks Daniel] (or on any constraints you may have placed on T, I assume), so you can't use it. You can only call operators, methods, properties on T that can be called on ALL possible types represented by T.
operator == calls 'Equals' in many cases, but that doesn't mean they are the same thing.
The ==
token is used to represent two different operators in C#. The first of them is applicable only if the types of the operands fit a particular defined overload of the "equality-check" operator. The second test reference equality and is applicable only if one operand is null
, one operand is a class type and the other an interface that instances of that type could implement, both are interfaces, both are the same class types, or both are class types and one is a supertype of the other. The first form will not be usable on a generic unless the generic is constrained to a type for which an equality-check overload is defined; the second form is limited to reference types which are known to satisfy a particular one of the indicated conditions. Note that in some cases, the second operator may be used where the first would be intended, e.g. bool IsSame<T>(T p1, T p2) where T:class { return p1==p2; }
will compare two variables of type String
by using a reference comparison, even though an overload of ==
is defined for String
. This occurs because T
isn't well-enough known to apply a String
overload of ==
, but both operands of ==
are known to be the same reference type.
It may be worth noting that some other languages use different tokens for the two operations C# performs using ==
. VB.NET, for example, uses =
for equality comparison and Is
for reference equality.
精彩评论