Similar questions have been asked, but I'm not sure I understand the answers correctly. I am referring to a situation where the equality operator is overridden in one or both classes. Please explain if I'm right. If I write if(a == b) { ... }
, then equality operator of the class of "a" is used and in case of if(b == a) { ... }
is used then equality operator defined in the class of "b". The equality operator of which class is used if I write if(null == a) { ... }
.
situation where the equality operator is overridden in one or both classes
We can do that and test... something like the following?
class A
{
public static bool operator == (A a, B b)
{
Console.WriteLine("A");
return false;
}
public static bool operator != (A a, B b)
{
Console.WriteLine("A");
return false;
}
public static bool operator == (B b, A a)
{
Console.WriteLine("A");
return false;
}
public static bool operator != (B b, A a)
{
Console.WriteLine("A");
return false;
}
public override bool Equals(object o)
{
return false;
}
public override int GetHashCode()
{
return 0;
}
}
class B
{
public static bool operator == (A a, B b)
{
Console.WriteLine("B");
return false;
}
public static bool operator != (A a, B b)
{
Console.WriteLine("B");
return false;
}
public static bool operator == (B b, A a)
{
Console.WriteLine("B");
return false;
}
public static bool operator != (B b, A a)
{
Console.WriteLine("B");
return false;
}
public override bool Equals(object o)
{
return false;
}
public override int GetHashCode()
{
return 0;
}
}
Then you write code such as:
A a = new A();
B b = new B();
if (a == b)
{
// ...
}
Then you get:
CS0034 Operator '==' is ambiguous on operands of type 'A' and 'B'
Does that answer your question? Have a look at the code, when you define the operator ==
you specify the types of the parameters, and the compiler uses that to choose the operator to call. In this case it finds two operators that have operands A
and B
in that order and that results in an ambiguous call (the compiler does not know - does not have a way to decide - which one to use).
If I write
if(a == b) { ... }
, then equality operator of the class of "a" is used and in case ofif(b == a) { ... }
is used then equality operator defined in the class of "b"
That depends on the types of the operands. If you always put the operant of the type of the current class as first, then that is true. For example:
void Main()
{
A a = new A();
B b = new B();
if (a == b)
{
// ...
}
}
class A
{
public static bool operator == (A a, B b)
{
Console.WriteLine("A");
return false;
}
public static bool operator != (A a, B b)
{
Console.WriteLine("A");
return false;
}
public override bool Equals(object o)
{
return false;
}
public override int GetHashCode()
{
return 0;
}
}
class B
{
public static bool operator == (B b, A a)
{
Console.WriteLine("B");
return false;
}
public static bool operator != (B b, A a)
{
Console.WriteLine("B");
return false;
}
public override bool Equals(object o)
{
return false;
}
public override int GetHashCode()
{
return 0;
}
}
Output: A
.
However, if define the operators with the operands in the opposite order...
void Main()
{
A a = new A();
B b = new B();
if (a == b)
{
// ...
}
}
class A
{
public static bool operator == (B b, A a)
{
Console.WriteLine("A");
return false;
}
public static bool operator != (B b, A a)
{
Console.WriteLine("A");
return false;
}
public override bool Equals(object o)
{
return false;
}
public override int GetHashCode()
{
return 0;
}
}
class B
{
public static bool operator == (A a, B b)
{
Console.WriteLine("B");
return false;
}
public static bool operator != (A a, B b)
{
Console.WriteLine("B");
return false;
}
public override bool Equals(object o)
{
return false;
}
public override int GetHashCode()
{
return 0;
}
}
Output: B
.
The equality operator of which class is used if I write
if(null == a) { ... }
First, let us be clear. B
or any other classes are irrelevant here. They do not affect the outcome of this comparison, because you are not using them here. It would be very inconvenient if they did.
Let us try:
void Main()
{
A a = new A();
if (null == a)
{
// ...
}
}
class A
{
public static bool operator == (A a, B b)
{
Console.WriteLine("A");
return false;
}
public static bool operator != (A a, B b)
{
Console.WriteLine("A");
return false;
}
public override bool Equals(object o)
{
return false;
}
public override int GetHashCode()
{
return 0;
}
}
class B
{
public static bool operator == (B b, A a)
{
Console.WriteLine("B");
return false;
}
public static bool operator != (B b, A a)
{
Console.WriteLine("B");
return false;
}
public override bool Equals(object o)
{
return false;
}
public override int GetHashCode()
{
return 0;
}
}
Output: .
We get no output, because the called operator is none of the ones defined here... intead it is using the default operator (the one for object
).
Wait! What if I change the order of operands?
void Main()
{
A a = new A();
if (null == a)
{
// ...
}
}
class A
{
public static bool operator == (B b, A a)
{
Console.WriteLine("A");
return false;
}
public static bool operator != (B b, A a)
{
Console.WriteLine("A");
return false;
}
public override bool Equals(object o)
{
return false;
}
public override int GetHashCode()
{
return 0;
}
}
class B
{
public static bool operator == (A a, B b)
{
Console.WriteLine("B");
return false;
}
public static bool operator != (A a, B b)
{
Console.WriteLine("B");
return false;
}
public override bool Equals(object o)
{
return false;
}
public override int GetHashCode()
{
return 0;
}
}
Output: A
.
Now we are using the operator on A
because it matches the operand types better than the default operator does.