3

Basically I have some code where when it happens, I need to set some object equal to some expression. All of this "what to do" jazz is stored as a string. So I parse it, and use reflection to find the object I am doing it to. Now I need to find out how to store the value to this object. The problem is the value could be "1", "1*(5/2)", or "some string value". It would be really cool if I could have expressions like "this.SomeProperty" or "(x > 3 ? 4 : 5)".

Also, the object it is storing to, could be a string, int, double, or float at the minimum.

4
  • 1
    Have you reviewed the StackOverflow questions in this Google search? : google.com/… Commented Apr 11, 2011 at 19:15
  • See also codeproject.com/KB/cs/evalcscode.aspx Commented Apr 11, 2011 at 19:18
  • 1
    I actually ending up using the Microsoft.CSharp.CSharpCodeProvider to compile it as code and that works marvelously. Thankyou both for your help. Commented Apr 12, 2011 at 19:28
  • possible duplicate of operators as strings Commented May 31, 2013 at 16:32

2 Answers 2

1

The VS2008 samples included a nifty ExpressionParser which could be used as a generic expression parser (VS2008 Samples). With a few small updates, and a custom factory class, we can turn it into something a bit more expressive:

string expression = "(1 + 2)";
var func = FunctionFactory.Create<int>(expression);

Or:

expression = "(a * b)";
var func2 = FunctionFactory.Create<int, int, int>(expression, new[] { "a", "b" });

The return types of these Create methods are Func<> instances, which means we get nice strongly type delegates:

int result = func2(45, 100); // result = 450;

I've push the code to a gist

Update: I've recently blogged about this too.

Update 2, another example:

var person = new Person { Age = 5 };
string expression = "(Age == 5)";
var func3 = FunctionFactory.Create<Person, bool>(expression);

bool isFive = func3(person); // Should be true.
Sign up to request clarification or add additional context in comments.

4 Comments

That is nifty. I had no idea that FunctionFactory/ExpressionParser existed. It still involves manually parsing the parameters's values, but the overall outcome of the expression is automated.
@Nick - FunctionFactory is something I chucked together around the VS2008 ExpressionParser type. Feel free to use and abuse it from the gist :-)
This is awesome. Can you create an expression without knowing the parameter list (ie a and b in your example) beforehand? Like dynamically inferring the parameters from the expression string?
@Justin - I'm not convinced that would work without modifying the ExpressionParser to update the included ParameterExpression instances used to match the parameters. The problem I think would be that you probably couldn't differentiate between what is an operand (you pass in), and a property of a this instance (see update above).
0

Have you seen http://ncalc.codeplex.com ?

It's extensible, fast (e.g. has its own cache) enables you to provide custom functions and varaibles at run time by handling EvaluateFunction/EvaluateParameter events. Example expressions it can parse:

Expression e = new Expression("Round(Pow(Pi, 2) + Pow([Pi2], 2) + X, 2)"); 

  e.Parameters["Pi2"] = new Expression("Pi * Pi"); 
  e.Parameters["X"] = 10; 

  e.EvaluateParameter += delegate(string name, ParameterArgs args) 
    { 
      if (name == "Pi") 
      args.Result = 3.14; 
    }; 

  Debug.Assert(117.07 == e.Evaluate()); 

It also handles unicode & many data type natively. It comes with an antler file if you want to change the grammer. There is also a fork which supports MEF to load new functions.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.