I have a business logic, base on the pre-defined condition ( OperatorType
and compare value), validate if it is true or false. The problem here is the value is "typed", and with operator (greater/less/equal etc).
If ValueType
is Integer, then the value and compare value need to converted to Integer
first, then base on OperatorType
, do comparison.
I would like to know if I can have a general function, passing CompareValue
, Value
, ValueType
, OperatorType
and return 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; }
}
}
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;
}
}
Without further ado, to get you started:
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; }
}
}
This could do with a lot of improvement (better type checking, CultureInfo awareness and error handling). But, it's a start
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.