ByValueEqualityComparer.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / Common / Utils / ByValueEqualityComparer.cs / 1305376 / ByValueEqualityComparer.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner [....]
// @backupOwner [....] 
//--------------------------------------------------------------------- 

using System; 
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics; 
using System.Linq;
 
namespace System.Data.Common.Utils 
{
    ///  
    /// An implementation of IEqualityComparer<object> that compares byte[] instances by value, and
    /// delegates all other equality comparisons to a specified IEqualityComparer. In the default case,
    /// this provides by-value comparison for instances of the CLR equivalents of all EDM primitive types.
    ///  
    internal sealed class ByValueEqualityComparer : IEqualityComparer
    { 
        ///  
        /// Provides by-value comparison for instances of the CLR equivalents of all EDM primitive types.
        ///  
        internal static readonly ByValueEqualityComparer Default = new ByValueEqualityComparer();

        private ByValueEqualityComparer()
        { 
        }
 
        public new bool Equals(object x, object y) 
        {
            if (object.Equals(x, y)) 
            {
                return true;
            }
 
            // If x and y are both non-null byte arrays, then perform a by-value comparison
            // based on length and element values, otherwise defer to the default comparison. 
            // 
            byte[] xBytes = x as byte[];
            byte[] yBytes = y as byte[]; 
            if (xBytes != null && yBytes != null)
            {
                return CompareBinaryValues(xBytes, yBytes);
            } 

            return false; 
        } 

        public int GetHashCode(object obj) 
        {
            if (obj != null)
            {
                byte[] bytes = obj as byte[]; 
                if (bytes != null)
                { 
                    return ComputeBinaryHashCode(bytes, 0); 
                }
            } 
            else
            {
                return 0;
            } 

            return obj.GetHashCode(); 
        } 

        internal static int ComputeBinaryHashCode(byte[] bytes, int hashCode) 
        {
            Debug.Assert(bytes != null, "Byte array cannot be null");

            for (int i = 0, n = Math.Min(bytes.Length, 7); i < n; i++) 
            {
                hashCode = ((hashCode << 5) ^ bytes[i]); 
            } 
            return hashCode;
        } 

        internal static bool CompareBinaryValues(byte[] first, byte[] second)
        {
            Debug.Assert(first != null && second != null, "Arguments cannot be null"); 

            if (first.Length != second.Length) 
            { 
                return false;
            } 

            for (int i = 0; i < first.Length; i++)
            {
                if (first[i] != second[i]) 
                {
                    return false; 
                } 
            }
 
            return true;
        }
    }
 
    /// 
    /// Extends IComparer support to the (non-IComparable) byte[] type, based on by-value comparison. 
    ///  
    internal class ByValueComparer : IComparer
    { 
        internal static readonly IComparer Default = new ByValueComparer(Comparer.Default);

        private readonly IComparer nonByValueComparer;
        private ByValueComparer(IComparer comparer) 
        {
            Debug.Assert(comparer != null, "Non-ByValue comparer cannot be null"); 
            this.nonByValueComparer = comparer; 
        }
 
        int IComparer.Compare(object x, object y)
        {
            if (object.ReferenceEquals(x, y))
            { 
                return 0;
            } 
 

            //We can convert DBNulls to nulls for the purposes of comparison. 
            Debug.Assert(!((object.ReferenceEquals(x, DBNull.Value)) && (object.ReferenceEquals(y,DBNull.Value))), "object.ReferenceEquals should catch the case when both values are dbnull");
            if (object.ReferenceEquals(x, DBNull.Value))
            {
                x = null; 
            }
            if (object.ReferenceEquals(y, DBNull.Value)) 
            { 
                y = null;
            } 

            if (x != null && y != null)
            {
                byte[] xAsBytes = x as byte[]; 
                byte[] yAsBytes = y as byte[];
                if (xAsBytes != null && yAsBytes != null) 
                { 
                    int result = xAsBytes.Length - yAsBytes.Length;
                    if (result == 0) 
                    {
                        int idx = 0;
                        while (result == 0 && idx < xAsBytes.Length)
                        { 
                            byte xVal = xAsBytes[idx];
                            byte yVal = yAsBytes[idx]; 
                            if (xVal != yVal) 
                            {
                                result = xVal - yVal; 
                            }
                            idx++;
                        }
                    } 
                    return result;
                } 
            } 

            return this.nonByValueComparer.Compare(x, y); 
        }
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

                        

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