operator overload not honored in a generic class

F

Fred Mellender

The code below shows that a statement in class Compare1, using the ==, does
not take the overloaded
operator (in class Foo). It appears to be just executing a ReferenceEqual
instead of resolving the overloaded
operator.

I might be misunderstanding the C# language at some point. Could someone
look at the code and tell me
why the overloaded operator is not executing for "==" but does execute for
"obj1.Equals(obj2).
---------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Foo
{
public class Compare1<T> where T: class
{
public static bool Equal(T obj1, T obj2)
{
return (obj1 == obj2); //this is the statement that does not
honor overloaded operator in class Foo

}
}

public class Compare2<T>
{
public static bool Equal(T obj1, T obj2)
{
return obj1.Equals(obj2); //works fine: honors overloaded
Equals in class Foo
}
}

public class Foo
{
public string val;

public Foo(string val)
{
this.val = val;
}

public override bool Equals(object obj)
{
Foo aFoo = obj as Foo;
if (ReferenceEquals(aFoo, null))
return false;
return aFoo.val == this.val;
}

public static bool operator == (Foo one, Foo two)
{
return one.Equals(two);
}
public static bool operator !=(Foo one, Foo two)
{
return !one.Equals(two);
}

public override int GetHashCode()
{
return base.GetHashCode();
}
}


public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
Foo foo1 = new Foo("A");
Foo foo2 = new Foo("A");
bool one = (foo1 == foo2); //returns true as expected. This is
the code also occuring when 'three" gives wrong answer
bool two = foo1.Equals(foo2); //returns true as expected
bool three = Compare1<Foo>.Equal(foo1, foo2); //this
statement returns false: should be true!!!!
bool four = Compare2<Foo>.Equal(foo1, foo2); //returns true as
expected
}
}
}

-- -
Fred Mellender
 
P

Peter Duniho

The code below shows that a statement in class Compare1, using the ==,
does not take the overloaded
operator (in class Foo). It appears to be just executing a
ReferenceEqual instead of resolving the overloaded
operator.

I might be misunderstanding the C# language at some point. Could
someone look at the code and tell me
why the overloaded operator is not executing for "==" but does execute
for "obj1.Equals(obj2).

Overload selection is done at compile time. And when the code using "=="
is compiled, the actual type for T is not known. The only "==" available
to the compiler is the base Object one, which of course does a reference
equality comparison.

Operator overloads can be tricky. Even outside of a generic context you
can get similar problems, because overloads are chosen based on the
contextual type of the operands, not the actual run-time types of the
operands. Overloading should be used with caution, and your example is a
good reason to prefer an equivalent virtual method when available.

Pete
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top