Search code examples
c#.netiequalitycomparerreferenceequals

IEqualityComparer<T> that uses ReferenceEquals


Is there a default IEqualityComparer<T> implementation that uses ReferenceEquals?

EqualityComparer<T>.Default uses ObjectComparer, which uses object.Equals(). In my case, the objects already implement IEquatable<T>, which I need to ignore and compare by object's reference only.


Solution

  • Just in case there is no default implementation, this is my own:

    Edit by 280Z28: Rationale for using RuntimeHelpers.GetHashCode(object), which many of you probably haven't seen before. :) This method has two effects that make it the correct call for this implementation:

    1. It returns 0 when the object is null. Since ReferenceEquals works for null parameters, so should the comparer's implementation of GetHashCode().
    2. It calls Object.GetHashCode() non-virtually. ReferenceEquals specifically ignores any overrides of Equals, so the implementation of GetHashCode() should use a special method that matches the effect of ReferenceEquals, which is exactly what RuntimeHelpers.GetHashCode is for.

    [end 280Z28]

    using System;
    using System.Collections.Generic;
    using System.Runtime.CompilerServices;
    
    /// <summary>
    /// A generic object comparerer that would only use object's reference, 
    /// ignoring any <see cref="IEquatable{T}"/> or <see cref="object.Equals(object)"/>  overrides.
    /// </summary>
    public class ObjectReferenceEqualityComparer<T> : EqualityComparer<T>
        where T : class
    {
        private static IEqualityComparer<T> _defaultComparer;
    
        public new static IEqualityComparer<T> Default
        {
            get { return _defaultComparer ?? (_defaultComparer = new ObjectReferenceEqualityComparer<T>()); }
        }
    
        #region IEqualityComparer<T> Members
    
        public override bool Equals(T x, T y)
        {
            return ReferenceEquals(x, y);
        }
    
        public override int GetHashCode(T obj)
        {
            return RuntimeHelpers.GetHashCode(obj);
        }
    
        #endregion
    }