C# convert a string for use in a logical condition

感情迁移 提交于 2019-11-30 11:32:37

You could do something like this:

public static bool Compare<T>(string op, T x, T y) where T:IComparable
{
 switch(op)
 {
  case "==" : return x.CompareTo(y)==0;
  case "!=" : return x.CompareTo(y)!=0;
  case ">"  : return x.CompareTo(y)>0;
  case ">=" : return x.CompareTo(y)>=0;
  case "<"  : return x.CompareTo(y)<0;
  case "<=" : return x.CompareTo(y)<=0;
 }
}

EDIT

As JaredPar pointed out, my suggestion below won't work as you can't apply the operators to generics...

So you'd need to have specific implementations for each types you wanted to compare/compute...

public int Compute (int param1, int param2, string op) 
{
    switch(op)
    {
        case "+": return param1 + param2;
        default: throw new NotImplementedException();
    }
}

public double Compute (double param1, double param2, string op) 
{
    switch(op)
    {
        case "+": return param1 + param2;
        default: throw new NotImplementedException();
    }
}

ORIG

You could do something like this.

You'd also need to try/catch all this to ensure that whatever T is, supports the particular operations.

Mind if I ask why you would possibly need to do this. Are you writing some sort of mathematical parser ?

public T Compute<T> (T param1, T param2, string op) where T : struct
{
    switch(op)
    {
        case "+":
            return param1 + param2;
        default:
             throw new NotImplementedException();
    }
}

public bool Compare<T> (T param1, T param2, string op) where T : struct
{
    switch (op)
    {
        case "==":
             return param1 == param2;
        default:
             throw new NotImplementedException();
    }
}

No, it's not possible, and why the hell would you wnat to do this?

You could, of course, create a function like:

 public static bool Compare<T>(char op, T a, T b);

You should look into using .NET 3.5's Expression trees. You can build expressions manually into an expression tree (basically an AST), and then call Expression.Compile() to create a callable delegate. Your LogicRule.Test() method would need to build the Expression tree, wrap the tree in a LambdaExpression that takes the object your applying the rules too as an argument, calls Compile(), and invokes the resulting delegate.

I've done something similar to this with the help of:

http://flee.codeplex.com/

This tool can essentially evaulate a wide range of expressions. Basic usage would be to pass in a string like '3 > 4' and the tool would return false.

However, you can also create an instance of the evaluator and pass in object name/value pairs and it can be a little more intuitive IE: myObject^7 < yourObject.

There is a ton more functionality that you can dive into at the codeplex site.

<Function = "PredicateMore" Param1 = "Object1.Value" Param2 = "0"/>

I think you can achieve exactly this using implicit casting. Something like:

   public static implicit operator Operator(string op) 
   {
      switch(op) {  
         case "==" : 
            return new EqualOperator();
            ...
      }
   }

   Operator op = "<";
   if( op.Compare(x,y) ) { ... }
   //or whatever use syntax you want for Operator.

Vici Parser (open-source) may be of help to you. It's a C# expression parser where you can just pass a string containing an expression, and you get the computed result back.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!