C#一般比较数字

时间:2018-09-18 17:52:13

标签: c#

我正在编写一个接受任何原始类型数字的函数,并确定该数字支持的最小类型:

public static Type GetSmallestType( decimal value )
{
  return
    value.CompareTo( sbyte.MinValue ) >= 0 && value.CompareTo( sbyte.MaxValue ) <= 0 ? typeof( sbyte ) :
    value.CompareTo( byte.MinValue ) >= 0 && value.CompareTo( byte.MaxValue ) <= 0 ? typeof( byte ) :
    value.CompareTo( short.MinValue ) >= 0 && value.CompareTo( short.MaxValue ) <= 0 ? typeof( short ) :
    value.CompareTo( ushort.MinValue ) >= 0 && value.CompareTo( ushort.MaxValue ) <= 0 ? typeof( ushort ) :
    value.CompareTo( int.MinValue ) >= 0 && value.CompareTo( int.MaxValue ) <= 0 ? typeof( int ) :
    value.CompareTo( uint.MinValue ) >= 0 && value.CompareTo( uint.MaxValue ) <= 0 ? typeof( uint ) :
    value.CompareTo( long.MinValue ) >= 0 && value.CompareTo( long.MaxValue ) <= 0 ? typeof( long ) :
    value.CompareTo( ulong.MinValue ) >= 0 && value.CompareTo( ulong.MaxValue ) <= 0 ? typeof( ulong ) :
    typeof( decimal );
}

// e.g. GetSmallestType( -10 ) == typeof( sbyte )

此实现有效,但我想避免每种类型的方法都有重载的方法,因为这会导致很多重复的代码。

当我尝试将其转换为接受通用参数的通用函数时,会引发错误,指出Object must be of type Int32

public static Type GetSmallestType<T>( T value )
  where T : struct, IComparable, IComparable<T>, IConvertible, IEquatable<T>, IFormattable
{ ... }

目标是将值转换为最小的可用类型(通过上述方法返回)并将其存储在通用树节点中。 然后这个问题成为能够比较所有原始类型(无论是使用强制转换还是其他方法)的一个问题,因为许多原始类型不能直接比较。

这是一个(可能是不必要的)内存优化问题,我想以此为乐。

1 个答案:

答案 0 :(得分:-2)

您可以将两者都强制转换为动态。是的,它不能达到使用泛型方法的目的,但是如果类型是数字,它就可以工作。 struct约束将有助于防止类被传递。

看来ulong不适用于此方法,但其他所有方法都可以。

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(GetSmallestType(100)); // System.SByte
        Console.WriteLine(GetSmallestType(200)); // System.Byte
        Console.WriteLine(GetSmallestType(30_000)); // System.Int16
        Console.WriteLine(GetSmallestType(60_000)); // System.UInt15
        Console.WriteLine(GetSmallestType(100_000)); // System.Int32
        Console.WriteLine(GetSmallestType(4_000_000_000)); // System.UInt23
        Console.WriteLine(GetSmallestType(100_000_000_000)); // System.Int64
        Console.WriteLine(GetSmallestType(20_000_000_000_000_000_000m)); // System.Decimal
    }

    public static Type GetSmallestType<T>(T propertyValue)
        where T : struct
    {
        dynamic value = propertyValue;

        return
            value >= (dynamic)sbyte.MinValue && value <= (dynamic)sbyte.MaxValue ? typeof(sbyte) :
            value >= (dynamic)byte.MinValue && value <= (dynamic)byte.MaxValue ? typeof(byte) :
            value >= (dynamic)short.MinValue && value <= (dynamic)short.MaxValue ? typeof(short) :
            value >= (dynamic)ushort.MinValue && value <= (dynamic)ushort.MaxValue ? typeof(ushort) :
            value >= (dynamic)int.MinValue && value <= (dynamic)int.MaxValue ? typeof(int) :
            value >= (dynamic)uint.MinValue && value <= (dynamic)uint.MaxValue ? typeof(uint) :
            value >= (dynamic)long.MinValue && value <= (dynamic)long.MaxValue ? typeof(long) :
            typeof(decimal);
    }
}