我需要找出decimal
值是否适合某种类型(在运行时检测到目标类型),如果不是,则将其截断为最大值或最小值,以便我可以通过网络发送它。.NET Framework中是否有某些东西来检查某个值是否适合某种类型?
我想避免与类型的大开关句子,我想可能已经有一些在.NET Framework中。
我需要找出decimal
值是否适合某种类型(在运行时检测到目标类型),如果不是,则将其截断为最大值或最小值,以便我可以通过网络发送它。.NET Framework中是否有某些东西来检查某个值是否适合某种类型?
我想避免与类型的大开关句子,我想可能已经有一些在.NET Framework中。
此操作在信号处理中有一个名称:clipping。
而这里是完全无用DecimalRestrictor<T>
,基于形式
x => x <= min ? min : x >= max ? max : (T)x;
一个dinamically内置表达式树加上decimal
,float
和double
一个例外:所有的三种类型可以接受任何decimal
值。
的代码:
public static class DecimalClipper<T>
{
public static readonly Func<decimal, T> Clip;
static DecimalClipper()
{
ParameterExpression value = Expression.Parameter(typeof(decimal), "value");
Expression<Func<decimal, T>> lambda;
if (typeof(T) == typeof(decimal))
{
lambda = Expression.Lambda<Func<decimal, T>>(value, value);
}
else if (typeof(T) == typeof(float) || typeof(T) == typeof(double))
{
lambda = Expression.Lambda<Func<decimal, T>>(Expression.Convert(value, typeof(T)), value);
}
else
{
T min = (T)typeof(T).GetField("MinValue", BindingFlags.Static | BindingFlags.Public).GetValue(null);
Expression minT = Expression.Constant(min);
Expression minDecimal = Expression.Constant(Convert.ToDecimal(min));
T max = (T)typeof(T).GetField("MaxValue", BindingFlags.Static | BindingFlags.Public).GetValue(null);
Expression maxT = Expression.Constant(max);
Expression maxDecimal = Expression.Constant(Convert.ToDecimal(max));
UnaryExpression cast = Expression.Convert(value, typeof(T));
ConditionalExpression greaterThanOrEqual = Expression.Condition(Expression.GreaterThanOrEqual(value, maxDecimal), maxT, cast);
ConditionalExpression lesserThanOrEqual = Expression.Condition(Expression.LessThanOrEqual(value, minDecimal), minT, greaterThanOrEqual);
lambda = Expression.Lambda<Func<decimal, T>>(lesserThanOrEqual, value);
}
Clip = lambda.Compile();
}
}
public static class DecimalEx
{
public static T Clip<T>(this decimal value)
{
return DecimalClipper<T>.Clip(value);
}
}
我甚至包括一个扩展方法...使用
实例:
int i1 = decimal.MaxValue.Clip<int>();
int i2 = decimal.MinValue.Clip<int>();
int i3 = 5.5M.Clip<int>();
int i4 = -5.5M.Clip<int>();
byte i5 =(-5.5M).Clip<byte>();
//char i6 = decimal.MaxValue.Clip<char>();
float i7 = decimal.MaxValue.Clip<float>();
double i8 = decimal.MaxValue.Clip<double>();
decimal i9 = decimal.MaxValue.Clip<decimal>();
嗯...仅产生的表达式树一次为每种类型T
使用,然后缓存感谢泛型类型和静态成员的工作。
目前不支持char
,IntPtr
,UIntPtr
。
这将是我的解决方案;
using System;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
decimal value = 123456.789M;
Console.WriteLine(ConvertOrMinMax<Byte>(value));
Console.WriteLine(ConvertOrMinMax<Int16>(value));
Console.WriteLine(ConvertOrMinMax<Int32>(value));
Console.WriteLine(ConvertOrMinMax<Int64>(value));
Console.WriteLine(ConvertOrMinMax<Decimal>(value));
Console.WriteLine(ConvertOrMinMax<Double>(value));
Console.WriteLine(ConvertOrMinMax<float>(value));
Console.Read();
}
static T ConvertOrMinMax<T>(decimal v)
{
var myType = typeof(T);
if(myType == typeof(double) || myType == typeof(float))
return (T)Convert.ChangeType(v, myType);
decimal min = (decimal)Convert.ChangeType(myType.GetField("MinValue").GetValue(null), typeof(decimal));
if (v < min)
return (T)Convert.ChangeType(min, myType);
decimal max = (decimal)Convert.ChangeType(myType.GetField("MaxValue").GetValue(null), typeof(decimal)); ;
if (v > max)
return (T)Convert.ChangeType(max, myType);
return (T)Convert.ChangeType(v, myType);
}
}
}
您是如何获得价值的?它是否有其他类型或文本? –
它是存储该值的小数。在问题中添加,谢谢 –
所以,你想把它放在最小的类型,将举行? –