Is it reference or value equality?
26 08 2004Probably reference. Checking for value equality is unintuitive - by default == is a reference equality check.
object a = 1;
object b = 1;
Assert.IsFalse (a == b);
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:
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);
}
}
Categories : .NET, c#






