c# - .NET Framework 中是否有一些东西可以检查一个值是否适合一个类型?

标签 c# .net validation types casting

我需要确定 decimal 值是否适合某种类型(在运行时检测到目标类型),如果不适合,则将其截断为其最大值或最小值,以便我可以通过网络。

我想避免带有类型的大 switch 语句,我认为 .NET Framework 中可能已经有一些东西。

最佳答案

这个 Action 在信号处理中有一个名字:clipping .

这里有一个完全没用的DecimalRestrictor<T> ,基于形式为动态构建的表达式树

x => x <= min ? min : x >= max ? max : (T)x;

加上 decimal 的异常(exception)情况, floatdouble : 所有三种类型都可以接受任何 decimal值(value)。

代码:

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目前不支持。

关于c# - .NET Framework 中是否有一些东西可以检查一个值是否适合一个类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30167387/

相关文章:

c# - C# .NET 框架的哪些部分实际上是该语言的一部分?

c# - 动态获取本地化字符串 WP8 c#

.net - 使用真实IP加密发送到托管在服务器上的WCF服务的消息

c# - 内联代码执行完成后是否将[写入其中的]方法保留在内存中?

jquery - jQuery验证插件,更改 'invalid'上的类

python - 在 "validation"类中使用异常或返回状态代码更好吗?

c# - 异步函数进行异步调用

c# - 在 C# 中具有我自己的属性的 StructureMap

c# - 流关闭后文件保持锁定状态

c++ - 尝试了解输入验证循环