Sunday, February 27, 2011

What is Dynamic Linq Expression and creating DynamicMethods

Before going to details of dynamic concepts lets make our understanding about static more clear.Below is a normal method we all learned when we started programming.

public int Add(int a, int b)
{
return a + b + 10;
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
MessageBox.Show(Add(1, 2).ToString());
}


This is nothing but 2 methods.One is  Add which adds 10 to the sum of the passed arguments.Another is to call the Add method by passing parameters 1,2.The result will be 13.No doubt in that.Lets look at the below code which I will say equivalent of the same but less lines.

private void Window_Loaded(object sender, RoutedEventArgs e)
{
MessageBox.Show(
new Func<int, int, int>((a, b) => a + b + 10)(1, 2)
.ToString());
}


Where is the Add method? You can see it as a lambda expression.The lambda function is executed by passing the arguments 1,2 and displays 13 as result.Don’t confuse on the Func.Its a delegate type not any special keyword.

These are static  : You can see that the execution logic is hard coded at the compile time itself.Or in other words by looking at the code, we can tell that how this is going to execute.Hope the word static is clear.Lets go to the dynamic world.

Dynamic Method

Here the method body is constructed at the runtime.The compiler is not compiling this methos and making any byte code for storing in assembly file. This is implemented through Expression classes available in .Net.

Concepts of Expression

If you had studied the compiler subject in your college days properly, you know that our code is constructed of expressions.If we write a=b in C# ,its an assignment expression.for loop is another type of expression.Try block is again another expression type.In short all the statements which we writing in our code is seen as an expression by the compiler.

That’s fine.Have you ever thought of a scenario where you need to create the code dynamically and compile as a method which should execute on the fly? If yes the System.Linq.Expressions namespace is for you.

Expression allows us to create code blocks dynamically as a expression tree using different types of sub expressions which can be compiled as a delegate object for execution.

We cannot say we are creating C# code ,but the equivalent object structure using classes which are derived from the base class Expression.ie we are creating objects which represent our code statement and relating them as how we write the code.The addition statement (a+b) is represented using an object of BinaryExpression. This has 2 properties Left and Right of type Expression again which are nothing but the parameters(a,b) to the + operator. While evaluating it behaves same as how our normal code runs.

using System.Linq.Expressions

This namespace contains a bunch of classes which helps us to create language expressions through code.The expression types include ParameterExpression, ConstantExpression, TryExpression and even the LambdaExpression. While creating your code expression tree use the appropriate classes and connect them properly as how you write code and finally create the LambdaExpression.LambdaExpression has the Compile method to get the delegate out of it. Execute the delegate to execute the created expression code.

Below is the Expression equivalent of the above static code.



private Delegate GetExpression()
{
ParameterExpression p1=ParameterExpression.Parameter(typeof(int),"a");
ParameterExpression p2=ParameterExpression.Parameter(typeof(int),"b");
ConstantExpression c=ConstantExpression.Constant(10);
BinaryExpression be1=BinaryExpression.Add(p1,p2);
BinaryExpression be2 = BinaryExpression.Add(be1, c);
LambdaExpression lambda = LambdaExpression.Lambda(be2, p1, p2);

return lambda.Compile();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
MessageBox.Show(GetExpression().DynamicInvoke(1, 2).ToString());
}


I don’t think there will be confusion in creating the Expressions and linking them.There are no constructors.You need to use the factory methods.Once the LambdaExpression is created you can Compile it to get the delegate.Invoke that delegate to execute your dynamic method code.

Expression Tree

By closely observing the object creation we could see the expression objects are linked as a tree structure .The root is the LambdaExpression.This is why it is called as expression tree.

Expression Tree is nothing but an object oriented representation of code.

I hope nobody have doubt on dynamism.By looking at this code we cannot say how the generated method will work.

Applications

There are lot of applications such as creating expression evaluators, even a new programming language of your own!!! According to my understanding the DLR is using these expressions.

If you had started in .Net from its 4.0 version you will say wow! what a feature.But if you are a developer who had worked in earlier versions one question might have popped up in your mind.Do we really need Linq Expression to generate code on the fly where we have CodeDom? Whether you have or not I have this question.Hope I can find the answer soon and share here.

No comments: