Operator overloading suprise

  • Thread starter Thread starter Peter
  • Start date Start date
P

Peter

The Operator overloading in C# has one limitation which I
have not seen stated explicitly anywhere.

Take the following example

public class A
{
int m_A;
public A(int a)
{
m_A = a;
}
public static bool operator==(A left, A right)
{
return left.m_A == right.m_A;
}
public static bool operator!=(A left, A right)
{
return left.m_A != right.m_A;
}
public static void Main()
{
A a1 = new A(1);
A a2 = new A(1);
System.Console.WriteLine((a1==a2).ToString());
object o1 = a1;
object o2 = a2;
System.Console.WriteLine((o1==o2).ToString());
}
}

I naively expected the output from this to be
true
true

but the actual output is
true
false

Because the operator is statically defined, the version of
== to be called is determined at compile time, hence
object.== is called rather than A.==

So rather than use == you must use the virtual method
Equals if you need to perform equality checks on
polymorphic objects.

This may be obvious to a lot of you folks out there, but it
was not obvious to me until I ran in to trouble with it.

Does anyone have any Idea why it was implemented in this way?
 
I'm going out on a limb a bit here, because I'm not 100% sure.

My best guess is that the methods are static because they do not belong in
any one particular instance. The purpose is purely to perform a comparison
between two instances, a non-static implementation would have implied that
the implementation of the operator could run methods, change properties etc.
of one particular instance. Also the question arises, which instance should
it be called from?

That's not a particularly great argument, I know.
 
Well, so you can always check for for reference equality, for one thing. I
think it's better to have the ability to check if two object references
point to the same instance. Plus you do have the overridable Equals which
is commonly known to check for equality as implemented by the instance
itself.

I agree there might have been another way to do this in the language.
Having == and .Equals() give different results has bugged me.

Richard
 
Well, so you can always check for for reference equality,
for one thing. I
think it's better to have the ability to check if two object references
point to the same instance.
I was after equality of the internal state, so I had to be
careful and use Equals where this was needed.
I agree there might have been another way to do this in the language.
Having == and .Equals() give different results has bugged me.

At the risk of going off topic...
I thought this would work in c++, but it doesn't. You are
not overriding a base class method because you have
different calling parameters. (I won't post a c++ code
snippet here ;)

So even if the operator was not defined as static in c# it
still would not override the base class, and the result
would be the same.

-----Original Message-----
Plus you do have the overridable Equals which
 
Reposting, forgot to fill in my name...
Well, so you can always check for for reference equality, for one thing. I
think it's better to have the ability to check if two object references
point to the same instance.
I was after equality of the internal state, so I had to be
careful and use Equals where this was needed.
I agree there might have been another way to do this in the language.
Having == and .Equals() give different results has bugged me.

At the risk of going off topic...
I thought this would work in c++, but it doesn't. You are
not overriding a base class method because you have
different calling parameters. (I won't post a c++ code
snippet here ;)

So even if the operator was not defined as static in c# it
still would not override the base class, and the result
would be the same.
 
Back
Top