/// <summary>
        /// Returns a new instance of <see cref="IEqualityComparer{T}"/> using the given implementation of <see cref="IEquatable{T}"/>.
        /// </summary>
        /// <typeparam name="T">The type of the objects to compare.</typeparam>
        /// <returns>A new instance of <see cref="IEqualityComparer{T}"/>.</returns>
        public static IEqualityComparer <T> FromIEquatable <T>()
            where T : IEquatable <T>
        {
            Type   type     = typeof(T);
            Object syncRoot = (_cache as ICollection).SyncRoot;
            IEqualityComparer <T> comparer = null;

            lock (syncRoot) {
                if (_cache.ContainsKey(type))
                {
                    comparer = _cache[type] as IEqualityComparer <T>;
                }
            }

            if (comparer == null)
            {
                EqualityComparison <T> equals = (x, y) => {
                    if (x == null && y == null)
                    {
                        return(true);
                    }

                    if (x != null && y != null)
                    {
                        return(x.Equals(y));
                    }

                    return(false);
                };

                comparer = new InternalEqualityComparer <T>(equals, (obj) => obj.GetHashCode());

                lock (syncRoot) {
                    if (!_cache.ContainsKey(type))
                    {
                        _cache.Add(type, comparer);
                    }
                }
            }

            return(comparer);
        }
예제 #2
0
        void Ctor()
        {
            IEqualityComparer comp   = null;
            Boolean           result = false;
            Int32             hash   = 0;

            Test.If.Action.ThrowsException(() => comp = new InternalEqualityComparer(null, null), out ArgumentNullException ex1);
            Test.If.Value.IsEqual(ex1.ParamName, "equals");

            Test.If.Action.ThrowsException(() => comp = new InternalEqualityComparer(null, (obj) => 42), out ex1);
            Test.If.Value.IsEqual(ex1.ParamName, "equals");

            Test.If.Action.ThrowsException(() => comp = new InternalEqualityComparer((x, y) => true, null), out ex1);
            Test.If.Value.IsEqual(ex1.ParamName, "getHashCode");

            Test.IfNot.Action.ThrowsException(() => comp = new InternalEqualityComparer((x, y) => true, (obj) => 42), out Exception ex2);

            result = comp.Equals(0, 1);
            Test.If.Value.IsEqual(result, true);

            hash = comp.GetHashCode(0);
            Test.If.Value.IsEqual(hash, 42);
        }