BigComparer.cs

Big Comparer Class

Includes: IBigEqualityComparer.cs

using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
[Serializable]
public class BigComparer<T> : IBigEqualityComparer<T>
{
    private static   Type            _type = typeof(T);
    private readonly BinaryFormatter _bf   = new BinaryFormatter();
    private readonly bool            _isPrimitive;
    private readonly MemoryStream    _ms = new MemoryStream();
    private          bool            _disposed;
    public BigComparer()
    {
        _isPrimitive = IsPrimitive();
    }
    public bool Equals(T x, T y)
    {
        if (x == null || y == null)
            return false;
        if (_isPrimitive)
            return x.Equals(y);
        if (_type == null)
            _type = x.GetType();
        if (_type.IsArray)
        {
            if (!_isPrimitive)
            {
                var xb = GetBytesObjectSerial(x);
                var yb = GetBytesObjectSerial(y);
                return xb.Compare(yb);
            }
            else
            {
                var xb = GetBytesObject(x);
                var yb = GetBytesObject(y);
                return xb.Compare(yb);
            }
        }
        return x.Equals(y);
    }
    public long GetHashCode(T obj)
    {
        if (_isPrimitive)
            return obj.GetHashCode();
        if (_type == null)
            _type = obj.GetType();
        var    result = 0xCBF29CE484222325;
        byte[] buf;
        buf = !_isPrimitive ? GetBytesObjectSerial(obj) : GetBytesObject(obj);
        foreach (var b in buf)
            result = (result ^ b) * 0x100000001B3;
        return (long) result;
    }
    private void Dispose(bool disposing)
    {
        if (!_disposed)
            if (disposing)
                _ms?.Close();
        _disposed = true;
    }
    public byte[] GetBytesObjectSerial(object value)
    {
        if (_type == null)
            _type = value.GetType();
        if (!_type.IsSerializable)
            throw new Exception("Error: Object is not Serializable.");
        _ms.SetLength(0);
        _bf.Serialize(_ms, value);
        return _ms.ToArray().SubArray(0, (int) _ms.Length);
    }
    public bool IsPrimitive()
    {
        if (_type == null)
            _type = typeof(T);
        switch (Type.GetTypeCode(_type))
        {
            case TypeCode.Boolean:
            case TypeCode.Char:
            case TypeCode.SByte:
            case TypeCode.Byte:
            case TypeCode.Int16:
            case TypeCode.UInt16:
            case TypeCode.Int32:
            case TypeCode.UInt32:
            case TypeCode.Single:
            case TypeCode.String:
            case TypeCode.Decimal:
            case TypeCode.DateTime:
            case TypeCode.Int64:
            case TypeCode.UInt64:
            case TypeCode.Double:
                return true;
            default:
                return false;
        }
    }
    public byte[] GetBytesObject(object obj)
    {
        if (_type == null)
            _type = obj.GetType();
        switch (_type.Name.Trim('[', ']'))
        {
            case "Byte":
                return !_type.IsArray ? new[] {(byte) obj} : (byte[]) obj;
            case "Boolean":
                return !_type.IsArray ? ((bool) obj).GetBytes() : ((bool[]) obj).GetBytes();
            case "SByte":
                return !_type.IsArray ? ((sbyte) obj).GetBytes() : ((sbyte[]) obj).GetBytes();
            case "Char":
                return !_type.IsArray ? ((char) obj).GetBytes() : ((char[]) obj).GetBytes();
            case "Int16":
                return !_type.IsArray ? ((short) obj).GetBytes() : ((short[]) obj).GetBytes();
            case "UInt16":
                return !_type.IsArray ? ((ushort) obj).GetBytes() : ((ushort[]) obj).GetBytes();
            case "Int32":
                return !_type.IsArray ? ((int) obj).GetBytes() : ((int[]) obj).GetBytes();
            case "UInt32":
                return !_type.IsArray ? ((uint) obj).GetBytes() : ((uint[]) obj).GetBytes();
            case "Int64":
                return !_type.IsArray ? ((long) obj).GetBytes() : ((long[]) obj).GetBytes();
            case "UInt64":
                return !_type.IsArray ? ((ulong) obj).GetBytes() : ((ulong[]) obj).GetBytes();
            case "Single":
                return !_type.IsArray ? ((float) obj).GetBytes() : ((float[]) obj).GetBytes();
            case "Double":
                return !_type.IsArray ? ((double) obj).GetBytes() : ((double[]) obj).GetBytes();
            case "String":
                return !_type.IsArray ? ((string) obj).GetBytes() : ((string[]) obj).GetBytes();
            case "Decimal":
                return !_type.IsArray ? ((decimal) obj).GetBytes() : ((decimal[]) obj).GetBytes();
            case "DateTime":
                return !_type.IsArray ? ((DateTime) obj).GetBytes() : ((DateTime[]) obj).GetBytes();
        }
        return GetBytesObjectSerial(obj);
    }
}

public interface IBigEqualityComparer<in T>
{
    bool Equals(T      x, T y);
    long GetHashCode(T obj);
}

public interface IBigEqualityComparer32<in T>
{
    bool Equals(T      x, T y);
    int GetHashCode(T obj);
}

Leave a Reply

Your email address will not be published. Required fields are marked *