Difference between Convert.ReferenceEquals() and Object.Equals()

K

Kevin B Ebert

Today, I ran into something I didn't quite expect. I'm sure there is
a logical explanation for it so I want to post it and see if anyone
can explain the difference to me.

I came across a situation when I wanted to see if a public variable
inside a struct was null or not. Sample code below:

namespace SampleConsole
{
/// <summary>
/// Summary description for Class1.
/// </summary>
class Init
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
MyStruct theStruct = new MyStruct();
theStruct.Variable1 = null;

try
{
if (theStruct.Variable1.Equals(null))
Console.WriteLine(".Equals evaluated");
}
catch
{
}

try
{
if (Convert.ReferenceEquals(theStruct.Variable1, null))
Console.WriteLine("ReferenceEquals evaluated");
}
catch
{
}
}
}
public struct MyStruct
{
public string Variable1;
public string Variable2;
}
}

What I found out was that theStruct.Variable1.Equals(null) throws an
System.NullReferenceException while
Convert.ReferenceEquals(theStruct.Variable1, null) returns true.
Well, there is clearly a difference between the two methods.

Looking in the MSDN library, I found the following definitions for the
two methods:

Object.Equals method: Determines whether two Object instances are
equal.
Convert.ReferenceEquals method: Determines whether the specified
Object instances are the same instance.

Well, I fail to see the difference in the two definitions. Being the
engineer that I am, I thought well let me look up the definition of a
System.NullReferenceException and the MSDN library offers:

The exception that is thrown when there is an attempt to dereference a
null object reference.

This doesn't help any either. Any thoughts?
 
J

Jeff Louie

Kevin... First. From a design point of view
someReference.Equals(someReference) is ugly since calling a method on
a null reference variable will throw a nullreferenceexception forcing
you
to either use an "assert" or check for null. A better design would be
static Equals(referenceOne, referenceTwo) which works even if one or
both references are null.

ReferenceEquals(o1,o2) uses this superior design and determines if two
references refer to the same object (referential equality). Therefore,
it
does not throw a nullreferenceexception even if one or both of the
operands are null.

Your class is supposed to override Equals to compare two objects by
value for _content_ equivalence. The base class Object has no way to
determine how to do this so the default implementation compares
objects by reference! Ugggg.

So. There is no guarantee what Equals does in a class. It should return
content equivalence, but it might return referential equality. It is
poorly
designed as it can throw a nullreferenceexception.

So. How about virtual Equals(o1,o2) in the next iteration of C#?

Regards,
Jeff
Object.Equals method: Determines whether two Object instances are
equal. Convert.ReferenceEquals method: Determines whether the
specified Object instances are the same instance. Well, I fail to see
the
difference in the two definitions.<
 

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