Click here to Skip to main content
15,881,882 members
Articles / Programming Languages / C# 3.5
Tip/Trick

Creating Func delegates using TextToCalcExpression

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
16 Mar 2012CPOL2 min read 9.6K   6  
This article how you can use TextToCalcExpression to generate Linq Expressions in runtime

Introduction

TextToCalcExpression is a project that i am developing on my free time, it's main goal it's to provide me and others with a free and simple to use LINQ Expressions generator for mathematical functions.

Background 

For quite some time I was on the lookout for expression compilers that have nice licenses and don't have external dependencies, namely to parser generator runtime libraries.

I have found some that met most of my criteria like Text To Delegate, which is very complete, but I wasn't too happy with the license and found the code difficult to change to my needs.

Having lost a lot of time searching I set my mind into hacking out an Linq Expression generator, that I could use as a library or embed into my projects.

Please note that TextToCalcExpression is pretty much into alpha territory, so there's still a lot of testing to do.

Using the code  

You can get the project's code on GitHub following this link.

After compiling and adding to one of your project's, using the code is rather simple.  

C#
ExpressionBuilder builder = new ExpressionBuilder();

Expression<Func<int,int, int>> expression = builder.Create<Func<int,int, int>>("A + B");
Func<int,int, int> func = expression.Compile();
int result = func(2,3);

 // which will result in getting a 5

The expression builder creates Lambda Expressions from text, for creating expressions you will need to choose which delegate you want to use, input types and output type. You can compile when you need it and use the delegate.

TextToCalcExpression supports arithmetical and logic operations, plus some useful functions (Sine, Cosine, Tangent, Square Root, etc). It will not, though, infer the output type from the resulting operation, so you must choose the correct generic parameters.

Here are some examples:  

C#
ExpressionBuilder builder = new ExpressionBuilder();

Expression<Func<int,int, int>> expression = 
                                builder.Create<Func<int,int, int>>("(A + 1) ^ B + 2");
Func<int,int, int> func = expression.Compile();
int result = func(2,3);

 // which will result in getting a 29

Expression<Func<bool,bool,bool>> expression2 = 
                 builder.Create<Func<bool,bool,bool>>("A==A AND (A!=B OR B==B)");
Func<bool,bool,bool> func2 = expression2.Compile();
bool result2 = func2(true,false);

 // which will result in getting a true value

You can add as many parameters as you need, but have in mind that the order of entry of the parameters will be the same as they appear in the function text.

If you need to use trigonometry or other available functions, here are some examples: 

C#
ExpressionBuilder builder = new ExpressionBuilder();

Expression<Func<double,double>> expression = 
                      builder.Create<Func<double, double>>("SIN(A)^2+COS(PI)^2");
Func<double,double> func = expression.Compile();

double result = func(Math.PI);

 // which will result in getting a 1

Expression<Func<double,double>> expression2 = builder.Create<Func<double, double>>("LN A");
Func<double,double> func2 = expression2.Compile();

double result2 = func2(Math.E);

 // which will result in getting a 1 also

Notice that PI and E constant are also available, so you can use them as well.

Keep in mind that TextToCalcExpression is case sensitive.

You can also use TextToCalcExpression to evaluate expressions, here are some examples of what is possible.

C#
ExpressionBuilder builder = new ExpressionBuilder();

Expression<Func<int>> expression = builder.Create<Func<int>>("(2^3+2-1)/3");
Func<int> func = expression.Compile();
int result = func();

 // which will result in getting a 3

Expression<Func<bool>> expression2 = builder.Create<Func<bool>>("NOT(false) AND true");
Func<bool> func2 = expression2.Compile();
bool result2 = func2();

 // which will result in getting a true value

Expression<Func<bool>> expression3 = builder.Create<Func<bool>>("2 > 3 AND 1 >= 2");
Func<bool> func3 = expression3.Compile();
bool result3 = func3();

 // which will result in getting a false value

Points of Interest

The primary idea on this expression generator is zero external dependencies, besides LINQ Expressions.

History

1st version - 2012/03/12.

2nd version - 2012/03/16.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Portugal Portugal
Software Dev Gun For Hire.

Comments and Discussions

 
-- There are no messages in this forum --