> In C# these are equivalent, right?
if (ReferenceEquals(objectA, objectB))
{
}
and
if (objectA == objectB)
{
}
The method System.Object.ReferenceEquals() always compares references.
Although a class can provide its own behavior for the equality operator
(below), that re-defined operator isn't invoked if the operator is called
via a reference to System.Object. Given this class:
public class EvenOdd
{
public int val;
public static bool operator==(EvenOdd left, EvenOdd right)
{
return left.val % 2 == right.val % 2;
}
public static bool operator!=(EvenOdd left, EvenOdd right)
{
return ! (left == right);
}
}
You'll get different results, depending on whether you invoke the comparison
via a reference to EvenOdd or a reference to System.Object.
If you create two EvenOdd instances:
EvenOdd a = new EvenOdd();
EvenOdd b = new EvenOdd();
a.val = 2;
b.val = 4;
Then call this method:
static void TestObject(object thing1, object thing2)
{
Console.WriteLine("Reference equals: {0}",
object.ReferenceEquals(thing1, thing2));
Console.WriteLine("Equality operator: {0}", thing1==thing2);
}
False is displayed twice to the console.
However, for a slightly different case:
static void TestEvenOdd(EvenOdd thing1, EvenOdd thing2)
{
Console.WriteLine("Reference equals: {0}",
object.ReferenceEquals(thing1, thing2));
Console.WriteLine("Equality operator: {0}", thing1 == thing2);
}
False is printed for the first case, and True for the second.
You might want to avoid this problem by overriding the virtual Equals method
if your redefinition of equality is meant to be true even when accessed via
a base type reference:
// EvenOdd, version 2
public class EvenOdd
{
public int val;
public static bool operator==(EvenOdd left, EvenOdd right)
{
return left.val % 2 == right.val % 2;
}
public static bool operator!=(EvenOdd left, EvenOdd right)
{
return ! (left == right);
}
public override bool Equals(object obj)
{
// Error-handling removed...
return ((EvenOdd)obj).val % 2 == val % 2;
}
}
With the Equals method, the proper equality comparison can be made through
any type of reference. This method displays False, then True (as expected):
static void TestEquals(object thing1, object thing2)
{
Console.WriteLine("Reference equals: {0}",
object.ReferenceEquals(thing1, thing2));
Console.WriteLine("Equals method: {0}", thing1.Equals(thing2));
}
--
Mickey Williams
Author, "Microsoft Visual C# .NET Core Reference", MS Press
www.servergeek.com/blogs/mickey