1

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

如果ValueType是Integer,则需要Integer先将值和比较值转换成,然后根据OperatorType,进行比较。

我想知道我是否可以有一个通用函数,传递CompareValue, Value, ValueType,OperatorType并返回真/假。

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; }
    }
}
4

2 回答 2

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;
    }
}
于 2013-03-19T12:06:41.653 回答
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 感知和错误处理)。但是,这是一个开始

于 2013-03-19T11:51:58.137 回答