与运算符的通用值和类型比较器

时间:2013-03-19 11:30:16

标签: c# generics compare

我有一个业务逻辑,基于预定义的条件(OperatorType并比较值),验证它是真还是假。这里的问题是值是“键入”,并且使用运算符(更大/更小/相等等)。

如果ValueType为整数,那么首先需要将值和比较值转换为Integer,然后基于OperatorType,进行比较。

我想知道我是否可以使用常规功能,传递CompareValueValueValueTypeOperatorType并返回true / false。

using System;
using System.Collections.Generic;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            var compare1 = 3;
            var foo1 = new Foo { Value = "2", OperatorType = OperatorTypes.GreaterOrEqual, ValueType = ValueTypes.Long };
            //compare compare1 and foo1.Value, output should be false (2 < 3)

            var compare2 = true;
            var foo2 = new Foo { Value = "True", OperatorType = OperatorTypes.Equal, ValueType = ValueTypes.Bool };
            //compare compare2 and foo2.Value, output should be true (true = true)

            var compare3 = DateTime.Parse("2013-03-19 15:00");
            var foo3 = new Foo { Value = "2013-03-19 16:00", OperatorType = OperatorTypes.Less, ValueType = ValueTypes.Date };
            //compare compare3 and foo3.Value, output should be false (2013-03-19 16:00 < 2013-03-19 15:00)
        }
    }

    public enum OperatorTypes : uint
    {
        Equal = 1,
        Greater = 2,
        GreaterOrEqual = 3,
        Less = 4,
        LessOrEqual = 5
    }

    public enum ValueTypes : uint
    {
        None = 0,
        Integer = 1,
        Long = 2,
        Numeric = 3,
        Date = 4,
        Text = 5,
        Bool = 6
    }

    class Foo
    {
        public string Value { get; set; }
        public ValueTypes ValueType { get; set; }
        public OperatorTypes OperatorType { get; set; }
    }
}

2 个答案:

答案 0 :(得分:2)

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(Compare<double>("123.1", 125.3, (a, b) => a > b));
        Console.WriteLine(Compare<DateTime>("19/03/2013", DateTime.Now, (a, b) => a == b));
    }

    private static bool Compare<T>(string valueAsString, T valueToComapare, Func<T,T,bool> check)
    {
        var asObject = (T)Convert.ChangeType(valueAsString, typeof(T));

        if (asObject != null)
        {
            return check(asObject, valueToComapare);
        }

        return false;
    }
}

答案 1 :(得分:1)

不用多说,为了让你开始:

using System;
using System.Diagnostics;
using System.Collections.Generic;

namespace Test
{
    class Program
    {
        public static dynamic CompareVal(Foo logic)
        {
            switch(logic.ValueType)
            {
                case ValueTypes.Integer: return Convert.ToInt32(logic.Value);
                case ValueTypes.Long:    return Convert.ToInt64(logic.Value);
                case ValueTypes.Numeric: return Convert.ToDecimal(logic.Value);
                case ValueTypes.Date:    return Convert.ToDateTime(logic.Value);
                case ValueTypes.Text:    return logic.Value;
                case ValueTypes.Bool:    return Convert.ToBoolean(logic.Value);
            }
            throw new InvalidProgramException("Unsupported ValueType");
        }

        public static bool Evaluate(dynamic val, Foo logic)
        {
            dynamic cmpval = CompareVal(logic);

            switch(logic.OperatorType)
            {
                case OperatorTypes.Equal:          return val == cmpval;
                case OperatorTypes.Greater:        return val >  cmpval;
                case OperatorTypes.GreaterOrEqual: return val >= cmpval;
                case OperatorTypes.Less:           return val <  cmpval;
                case OperatorTypes.LessOrEqual:    return val <= cmpval;
            }

            return false;
        }

        static void Main(string[] args)
        {
            //compare compare1 and foo1.Value, output should be false (2 < 3)
            Debug.Assert(false == Evaluate(3, new Foo 
                        { 
                            Value = "2", 
                            OperatorType = OperatorTypes.GreaterOrEqual, 
                            ValueType = ValueTypes.Long 
                        }));

            //compare compare2 and foo2.Value, output should be true (true = true)
            Debug.Assert(true == Evaluate(true, new Foo 
                        { 
                            Value = "True", 
                            OperatorType = OperatorTypes.Equal, 
                            ValueType = ValueTypes.Bool 
                        }));

            //compare compare3 and foo3.Value, output should be false (2013-03-19 16:00 < 2013-03-19 15:00)
            Debug.Assert(false == Evaluate(DateTime.Parse("2013-03-19 15:00"), new Foo 
                        { 
                            Value = "2013-03-19 16:00", 
                            OperatorType = OperatorTypes.Less, 
                            ValueType = ValueTypes.Date 
                        }));
        }
    }

    public enum OperatorTypes : uint
    {
        Equal = 1,
        Greater = 2,
        GreaterOrEqual = 3,
        Less = 4,
        LessOrEqual = 5
    }

    public enum ValueTypes : uint
    {
        None = 0,
        Integer = 1,
        Long = 2,
        Numeric = 3,
        Date = 4,
        Text = 5,
        Bool = 6
    }

    class Foo
    {
        public string Value { get; set; }
        public ValueTypes ValueType { get; set; }
        public OperatorTypes OperatorType { get; set; }
    }
}

这可以做很多改进(更好的类型检查,CultureInfo意识和错误处理)。但是,这是一个开始