Some code for context:
class a
{
}
class b
{
public a a{get;set;}
public static implicit operator a(b b)
{
return b.a;
}
}
a a=null;
b b=null;
a = b;
//compiler: cannot apply operator '==' to operands of type tralala...
bool c = a == b;
Is it possible to use == operator on different type instances, where one can implicitly convert to another? What did i miss?
Edit:
If types must be the same calling ==, then why
int a=1;
double b=1;
bool c=a==b;
works?
The implicit
operator only works for assignment.
You want to overload the equality (==
) operator, as such:
class a
{
public static bool operator ==(a x, b y)
{
return x == y.a;
}
public static bool operator !=(a x, b y)
{
return !(x == y);
}
}
class b
{
public a a{get;set;}
public static implicit operator a(b b)
{
return b.a;
}
}
This should then allow you to compare two objects of type a
and b
as suggested in your post.
var x = new a();
var y = new b();
bool c = (x == y); // compiles
Note:
I recommmend simply overriding the GetHashCode
and Equals
method, as the compiler warns, but as you seem to want to supress them, you can do that as follows.
Change your class declaration of a
to:
#pragma warning disable 0660, 0661
class a
#pragma warning restore 0660, 0661
{
// ...
}
Is it possible to use == operator on
different type instances, where one
can implicitly convert to another?
Yes.
What did i miss?
Here's the relevant portion of the specification. You missed the highlighted word.
The predefined reference type equality
operators require [that] both operands
are reference-type values or the
literal null. Furthermore, a standard
implicit conversion exists from the
type of either operand to the type of
the other operand.
A user-defined conversion is by definition not a standard conversion. These are reference types. Therefore, the predefined reference type equality operator is not a candidate.
If types must be the same calling ==,
then why [double == int] works?
Your supposition that the types must be the same is incorrect. There is a standard implicit conversion from int to double and there is an equality operator that takes two doubles, so this works.
I think you also missed this bit:
It is a compile-time error to use the
predefined reference type equality
operators to compare two references
that are known to be different at
compile-time. For example, if the
compile-time types of the operands are
two class types A and B, and if
neither A nor B derives from the
other, then it would be impossible for
the two operands to reference the same
object. Thus, the operation is
considered a compile-time error.
I would imagine that you need to actually override the == operator for the types you are interested in. Whether the compile/runtime will still complain even if the types are implicity convertable is something you'll have to experiment with.
public static bool operator ==(a a, b b)
{
//Need this check or we can't do obj == null in our Equals implementation
if (((Object)a) == null)
{
return false;
}
else
{
return a.Equals(b);
}
}
Alternatively just use Equals implementations like ole6ka suggests and ensure that the implementation does the type casting you need.
http://msdn.microsoft.com/en-us/library/8edha89s.aspx
In each case, one parameter must be
the same type as the class or struct
that declares the operator (...)