EqualityComparer.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / clr / src / BCL / System / Collections / Generic / EqualityComparer.cs / 1 / EqualityComparer.cs

                            // ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 

using System; 
using System.Collections; 
using System.Collections.Generic;
 
namespace System.Collections.Generic
{
    using System.Globalization;
    using System.Runtime.CompilerServices; 

    [Serializable()] 
    [TypeDependencyAttribute("System.Collections.Generic.GenericEqualityComparer`1")] 
    public abstract class EqualityComparer : IEqualityComparer, IEqualityComparer
    { 
        static EqualityComparer defaultComparer;

        public static EqualityComparer Default {
            get { 
                EqualityComparer comparer = defaultComparer;
                if (comparer == null) { 
                    comparer = CreateComparer(); 
                    defaultComparer = comparer;
                } 
                return comparer;
            }
        }
 
        private static EqualityComparer CreateComparer() {
            Type t = typeof(T); 
            // Specialize type byte for performance reasons 
            if (t == typeof(byte)) {
                return (EqualityComparer)(object)(new ByteEqualityComparer()); 
            }
            // If T implements IEquatable return a GenericEqualityComparer
            if (typeof(IEquatable).IsAssignableFrom(t)) {
                //return (EqualityComparer)Activator.CreateInstance(typeof(GenericEqualityComparer<>).MakeGenericType(t)); 
                return (EqualityComparer)(typeof(GenericEqualityComparer).TypeHandle.CreateInstanceForAnotherGenericParameter(t));
            } 
            // If T is a Nullable where U implements IEquatable return a NullableEqualityComparer 
            if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>)) {
                Type u = t.GetGenericArguments()[0]; 
                if (typeof(IEquatable<>).MakeGenericType(u).IsAssignableFrom(u)) {
                    //return (EqualityComparer)Activator.CreateInstance(typeof(NullableEqualityComparer<>).MakeGenericType(u));
                    return (EqualityComparer)(typeof(NullableEqualityComparer).TypeHandle.CreateInstanceForAnotherGenericParameter(u));
                } 
            }
            // Otherwise return an ObjectEqualityComparer 
            return new ObjectEqualityComparer(); 
        }
 
        public abstract bool Equals(T x, T y);
        public abstract int GetHashCode(T obj);

        internal virtual int IndexOf(T[] array, T value, int startIndex, int count) { 
            int endIndex = startIndex + count;
            for (int i = startIndex; i < endIndex; i++) { 
                if (Equals(array[i], value)) return i; 
            }
            return -1; 
        }

        internal virtual int LastIndexOf(T[] array, T value, int startIndex, int count) {
            int endIndex = startIndex - count + 1; 
            for (int i = startIndex; i >= endIndex; i--) {
                if (Equals(array[i], value)) return i; 
            } 
            return -1;
        } 

        int IEqualityComparer.GetHashCode(object obj) {
            if (obj == null) return 0;
            if (obj is T) return GetHashCode((T)obj); 
            ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArgumentForComparison);
            return 0; 
        } 

        bool IEqualityComparer.Equals(object x, object y) { 
            if (x == y) return true;
            if (x == null || y == null) return false;
            if ((x is T) && (y is T)) return Equals((T)x, (T)y);
            ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArgumentForComparison); 
            return false;
        } 
    } 

    // The methods in this class look identical to the inherited methods, but the calls 
    // to Equal bind to IEquatable.Equals(T) instead of Object.Equals(Object)
    [Serializable()]
    internal class GenericEqualityComparer: EqualityComparer where T: IEquatable
    { 
        public override bool Equals(T x, T y) {
            if (x != null) { 
                if (y != null) return x.Equals(y); 
                return false;
            } 
            if (y != null) return false;
            return true;
        }
 
        public override int GetHashCode(T obj) {
            if (obj == null) return 0; 
            return obj.GetHashCode(); 
        }
 
        internal override int IndexOf(T[] array, T value, int startIndex, int count) {
            int endIndex = startIndex + count;
            if (value == null) {
                for (int i = startIndex; i < endIndex; i++) { 
                    if (array[i] == null) return i;
                } 
            } 
            else {
                for (int i = startIndex; i < endIndex; i++) { 
                    if (array[i] != null && array[i].Equals(value)) return i;
                }
            }
            return -1; 
        }
 
        internal override int LastIndexOf(T[] array, T value, int startIndex, int count) { 
            int endIndex = startIndex - count + 1;
            if (value == null) { 
                for (int i = startIndex; i >= endIndex; i--) {
                    if (array[i] == null) return i;
                }
            } 
            else {
                for (int i = startIndex; i >= endIndex; i--) { 
                    if (array[i] != null && array[i].Equals(value)) return i; 
                }
            } 
            return -1;
        }

        // Equals method for the comparer itself. 
        public override bool Equals(Object obj){
            GenericEqualityComparer comparer = obj as GenericEqualityComparer; 
            return comparer != null; 
        }
 
        public override int GetHashCode() {
            return this.GetType().Name.GetHashCode();
        }
    } 

    [Serializable()] 
    internal class NullableEqualityComparer : EqualityComparer> where T : struct, IEquatable 
    {
        public override bool Equals(Nullable x, Nullable y) { 
            if (x.HasValue) {
                if (y.HasValue) return x.value.Equals(y.value);
                return false;
            } 
            if (y.HasValue) return false;
            return true; 
        } 

        public override int GetHashCode(Nullable obj) { 
            return obj.GetHashCode();
        }

        internal override int IndexOf(Nullable[] array, Nullable value, int startIndex, int count) { 
            int endIndex = startIndex + count;
            if (!value.HasValue) { 
                for (int i = startIndex; i < endIndex; i++) { 
                    if (!array[i].HasValue) return i;
                } 
            }
            else {
                for (int i = startIndex; i < endIndex; i++) {
                    if (array[i].HasValue && array[i].value.Equals(value.value)) return i; 
                }
            } 
            return -1; 
        }
 
        internal override int LastIndexOf(Nullable[] array, Nullable value, int startIndex, int count) {
            int endIndex = startIndex - count + 1;
            if (!value.HasValue) {
                for (int i = startIndex; i >= endIndex; i--) { 
                    if (!array[i].HasValue) return i;
                } 
            } 
            else {
                for (int i = startIndex; i >= endIndex; i--) { 
                    if (array[i].HasValue && array[i].value.Equals(value.value)) return i;
                }
            }
            return -1; 
        }
 
        // Equals method for the comparer itself. 
        public override bool Equals(Object obj){
            NullableEqualityComparer comparer = obj as NullableEqualityComparer; 
            return comparer != null;
        }

        public override int GetHashCode() { 
            return this.GetType().Name.GetHashCode();
        } 
    } 

    [Serializable()] 
    internal class ObjectEqualityComparer: EqualityComparer
    {
        public override bool Equals(T x, T y) {
            if (x != null) { 
                if (y != null) return x.Equals(y);
                return false; 
            } 
            if (y != null) return false;
            return true; 
        }

        public override int GetHashCode(T obj) {
            if (obj == null) return 0; 
            return obj.GetHashCode();
        } 
 
        internal override int IndexOf(T[] array, T value, int startIndex, int count) {
            int endIndex = startIndex + count; 
            if (value == null) {
                for (int i = startIndex; i < endIndex; i++) {
                    if (array[i] == null) return i;
                } 
            }
            else { 
                for (int i = startIndex; i < endIndex; i++) { 
                    if (array[i] != null && array[i].Equals(value)) return i;
                } 
            }
            return -1;
        }
 
        internal override int LastIndexOf(T[] array, T value, int startIndex, int count) {
            int endIndex = startIndex - count + 1; 
            if (value == null) { 
                for (int i = startIndex; i >= endIndex; i--) {
                    if (array[i] == null) return i; 
                }
            }
            else {
                for (int i = startIndex; i >= endIndex; i--) { 
                    if (array[i] != null && array[i].Equals(value)) return i;
                } 
            } 
            return -1;
        } 

        // Equals method for the comparer itself.
        public override bool Equals(Object obj){
            ObjectEqualityComparer comparer = obj as ObjectEqualityComparer; 
            return comparer != null;
        } 
 
        public override int GetHashCode() {
            return this.GetType().Name.GetHashCode(); 
        }
    }

    // Performance of IndexOf on byte array is very important for some scenarios. 
    // We will call the C runtime function memchr, which is optimized.
    [Serializable()] 
    internal class ByteEqualityComparer: EqualityComparer 
    {
        public override bool Equals(byte x, byte y) { 
            return x == y;
        }

        public override int GetHashCode(byte b) { 
            return b.GetHashCode();
        } 
 
        internal unsafe override int IndexOf(byte[] array, byte value, int startIndex, int count) {
            if (array==null) 
                throw new ArgumentNullException("array");
            if (startIndex < 0)
                throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
            if (count < 0) 
                throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Count"));
            if (count > array.Length - startIndex) 
                throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); 
            if (count == 0) return -1;
            fixed (byte* pbytes = array) { 
                return Buffer.IndexOfByte(pbytes, value, startIndex, count);
            }
        }
 
        internal override int LastIndexOf(byte[] array, byte value, int startIndex, int count) {
            int endIndex = startIndex - count + 1; 
            for (int i = startIndex; i >= endIndex; i--) { 
                if (array[i] == value) return i;
            } 
            return -1;
        }

        // Equals method for the comparer itself. 
        public override bool Equals(Object obj){
            ByteEqualityComparer comparer = obj as ByteEqualityComparer; 
            return comparer != null; 
        }
 
        public override int GetHashCode() {
            return this.GetType().Name.GetHashCode();
        }
 
    }
} 


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK