Tutorial :C#: Is there a way to use expressions as a variable/parameter?



Question:

I'd like to know if it is possible to use an expression as a variable/parameter in C#. I would like to do something like this:

int x = 0;  public void g()  {     bool greaterThan = f("x>2");     bool lessThan = f("x<2");  }  public bool f(Expression expression)  {     if(expression)         return true;     else         return false;  }  

Here's what I don't want to do:

int x = 0;  public void g()  {      bool greaterThan = f(x, '<', 2);  }    public bool f(int x, char c, int y)  {      if(c == '<')         return x < y;      if(c == '>')         return x > y;  }  

Really what I'm getting at is a way to get around using a switch or series of if statements for each of: < > <= >= == !=. Is there a way to do it?

Edit: Suppose that the expression is a string, like "x < 2". Is there a way to go from the string to a predicate without using a series of if statements on the condition?


Solution:1

Its very possible, just not in the exact syntax you have.

int x = 0;  public void g()  {     bool greaterThan = f(i => i > 2, x);     bool lessThan = f(i => i < 2, x);  }  public bool f(Func<int,bool> expression, int value)  {     return expression(value);  }  

Actually, this should be closer to what you want.

int x = 0;  public void g()  {     bool greaterThan = f(() => x > 2);     bool lessThan = f(() => x < 2);  }  public bool f(Func<bool> expression)  {     return expression();  }  

Reply to Edit

If you want be able to say f("x < 2"), it's going to be almost impossible. Ignoring parsing it (which could get nasty), you have to capture the value of x, but its just a character to f, which makes it pretty much impossible.


Solution:2

If you really want to pass around code for this, you want a Predicate:

int x = 0;  public void g()  {     bool greaterThan = f(i => i>2, x);     bool lessThan = f(i => i<2, x);  }  public bool f(Predicate<int> expression, int value)  {     return expression(value);  }  

Otherwise, if you just substitute bool for Expression in your first example your code would compile just fine:

int x = 0;  public void g()  {     bool greaterThan = f(x>2);     bool lessThan = f(x<2);  }  public bool f(bool expression)  {     if(expression)         return true;     else         return false;  }  


Solution:3

Unless I'm missing something... why don't you just do:

bool greaterThan = x > 5;  bool lessThan = x < 5;  

A boolean comparison already is an expression...

Edit:

So for your function, just pass a bool:

public void f(bool expression)   {      // expression is either true or false...  }    f(x<5); // called like this  


Solution:4

Edit: Suppose that the expression is a string, like "x < 2". Is there a way to go from the string to a predicate without using a series of if statements on the condition?

As some people have already mentioned; if you want to be able to use a string, you need parsing. You don't really want to write your own C# parser, luckily, some people at Microsoft already did that with Dynamic LINQ.

Here is a solution to your specific question:

public void g()  {      int x = 0;        bool greaterThan = f("x > 2", x);      bool lessThan = f("x < 2", x);  }    public bool f(string expression, int x)  {      ParameterExpression xExpr = Expression.Parameter(typeof(int), "x");        LambdaExpression e = DynamicExpression.ParseLambda(          new ParameterExpression[] { xExpr }, typeof(bool), expression);        return (bool)e.Compile().DynamicInvoke(x);  }  

Now, obviously, this will blow up on the slightest typo in the string. You really need to be thinking about whether you actually need this. But if you really do, you can use the DynamicExpression.ParseLambda method to parse strings into LambdaExpressions.


Solution:5

Edit: Suppose that the expression is a string, like "x < 2". Is there a way to go from the string to a predicate without using a series of if statements on the condition?

There are several tricks you can use to turn strings into code in .Net: CodeDom, Reflection.Emit, or even scripting the compiler in the shell. However, none of these are as simple as a quick eval() in scripting languages, and this is usually frowned upon in .Net anyway unless you really know what you're doing.

Instead, .Net provides the System.Addin namespace as a safer way to allow for user extensions to your application.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »