Thursday
Aug262004
Is it reference or value equality?
Thursday, August 26, 2004 at 9:03AM
Probably reference. Checking for value equality is unintuitive - by default == is a reference equality check.
Object a doesn't equal object b since boxing a as object created once instance, and boxing b created another. Since == is a "reference type equality operator", it will only compare the references.
Using any of these methods works fine:
When passing objects around, the simple solution is to use the Equals() method as it may perform value equality if the object overrides Equals(). So, value equality is somewhat easy to accomplish for individual objects, but you run into this problem again with collections:
There is only reference equality with ArrayList since Object.Equals() is inherited not overridden.
Here's my solution to perform value equality for collections. And now:
Here's a real world example:
object a = 1;object b = 1;Assert.IsFalse (a == b);
Using any of these methods works fine:
Assert.IsTrue (a.Equals (b));
Assert.IsTrue (((int)a).Equals (b));Assert.IsTrue (Object.Equals (a, b));Assert.IsTrue ((int)a == (int)b);
When passing objects around, the simple solution is to use the Equals() method as it may perform value equality if the object overrides Equals(). So, value equality is somewhat easy to accomplish for individual objects, but you run into this problem again with collections:
Assert.IsFalse (
new string[] { "abc", "def" }.Equals (
new string[] { "abc", "def" }));
Assert.IsFalse (new int[] { 1, 2, 3 }.Equals (new int[] { 1, 2, 3 }));
Assert.IsFalse (
new object[] { 4, "stuff", DateTime.Parse ("1/1/2004 1:00 AM") }.Equals (
new object[] { 4, "stuff", DateTime.Parse ("January 1, 2004 01:00") }));
There is only reference equality with ArrayList since Object.Equals() is inherited not overridden.
Assert.IsFalse (
new System.Collections.ArrayList (new int[] { 1, 2, 3 }) ==
new System.Collections.ArrayList (new int[] { 1, 2, 3 }));
Assert.IsFalse (
new System.Collections.ArrayList (new int[] { 1, 2, 3 }).Equals (
new System.Collections.ArrayList (new int[] { 1, 2, 3 })));
Here's my solution to perform value equality for collections. And now:
Assert.IsTrue (Collection.Equals (
new System.Collections.ArrayList (new int[] { 1, 2, 3 }),
new System.Collections.ArrayList (new int[] { 1, 2, 3 }), true));
Assert.IsTrue (Collection.Equals (
new int[] { 1, 2, 3 }, new System.Collections.ArrayList (
new int[] { 1, 2, 3 }), true));
Assert.IsTrue (Collection.Equals (
new object[] { 1, 2, 3 },
new int[] { 1, 2, 3 }), true);
Assert.IsTrue (Collection.Equals (
new object[] { 4, "stuff", DateTime.Parse ("1/1/2004 1:00 AM") },
new object[] { 4, "stuff", DateTime.Parse ("January 1, 2004 01:00") }), true);
Here's a real world example:
/// <summary>Always accepts the public key hardcoded in the byte array as a valid certificate.</summary>
public sealed class AcceptTrustedCertificate : ICertificatePolicy {
public bool CheckValidationResult (
ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem) { //TODO: verify certificateProblem is an acceptable value // return true if certificate returned is equal to the certificate's public key return Collection.Equals (certificate.GetPublicKey (),
new byte[] { 48, 130, 1, 10, 2, 130, 1, 1, 0, 206, 214, 212 }, true);
}
}

Reader Comments (3)
I am sure this will be helpful for more than a handful of people. Nicely done.
Good job! Although isn't it possible to do the same using IComparable? In fact in generics using the dictionary stack (I think) is able to the same thing. However, this is based on a Key value pair, this is a nice low level equality check. There might be other generic classes in .NET 2.0 that might address this short coming. Again good stuff!
Both the IComparable.CompareTo and IComparer.Compare method return if x > y, x = y, or x < y. This function only checks value equality for collections. I\'ve posted a RelaxComparer class that Implements the IComparer interface in a more relaxed way than the default Comparer class, and have implemented a CollectionEquality method that tests collection equality based on the value and count of each item in the collection, regardless of position.