在实际需求遇到需要根据不同条件,去指定不同的不同的审批人。起初的需求倒很简单,明确是当金额 >=500000 , 可变的就是500000这个数额。
当时为了防止可能产生的变化。特意搞了 条件 和金额这两个变量。但是只能满足单向的条件判断:= != >= <= > < 这几种。
需求是个唯变不变的东西。当条件变成 Amout>1000&&Amout<500000 开始有金额区间 的时候现有的方案满足不了。当然如果只是这种定式的还可以针对这种自己分解判断。 但是有点害怕终究有一天会变成(Amount>500||Type==1)&&Amount<50000&&Amount!=38888.
所以,需要一个万全之策:
百度了一圈关键字之后:
根据实际情况选用了CodeDom的方式,我这一块对性能没有太大的要求。原则上来说只要我的条件表达式满足c#的条件判断语法。就都能满足!Ok,很强大。
public class Util { public static object Eval(string sCSCode, string bianliang) { CodeDomProvider pro = new CSharpCodeProvider(); CompilerParameters cp = new CompilerParameters(); cp.ReferencedAssemblies.Add("system.dll"); cp.CompilerOptions = "/t:library"; cp.GenerateInMemory = true; StringBuilder sb = new StringBuilder(""); sb.Append("using System;\n"); sb.Append("namespace CSCodeEvaler{ \n"); sb.Append("public class CSCodeEvaler{ \n"); sb.Append("public object EvalCode(){\n"); sb.Append(bianliang); sb.Append("return " + sCSCode + "; \n"); sb.Append("} \n"); sb.Append("} \n"); sb.Append("}\n"); CompilerResults cr = pro.CompileAssemblyFromSource(cp, sb.ToString()); if (cr.Errors.Count > 0) { Console.WriteLine("ERROR: " + cr.Errors[0].ErrorText); return null; } System.Reflection.Assembly a = cr.CompiledAssembly; object o = a.CreateInstance("CSCodeEvaler.CSCodeEvaler"); Type t = o.GetType(); MethodInfo mi = t.GetMethod("EvalCode"); object s = mi.Invoke(o, null); return s; } }
static void Main(string[] args) { var result = Util.Eval("(Amount>500||Type==1)&&Amount<50000&&Amount!=38888", "int Amount=400;\n int Type=1;"); Console.WriteLine(result); var result2 = Util.Eval("(Amount>500||Type==1)&&Amount<50000&&Amount!=38888", "int Amount=38888;\n int Type=2;"); Console.WriteLine(result2); Console.ReadKey(); }
一套demo 三连:demo -》测试-》 结果 。满足!