我正在编写一个接受任何原始类型数字的函数,并确定该数字支持的最小类型:
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
{ ... }
目标是将值转换为最小的可用类型(通过上述方法返回)并将其存储在通用树节点中。 然后这个问题成为能够比较所有原始类型(无论是使用强制转换还是其他方法)的一个问题,因为许多原始类型不能直接比较。
这是一个(可能是不必要的)内存优化问题,我想以此为乐。
答案 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);
}
}