In this post we are gonna re-invent the LINQ's OrderBy extension method.
The implementation of OrderBy allows us to pass lambda expression in the form: x => x.Name
so to order list of students by name, you do the following:
var orderedStudents = allStudents.OrderBy(s => s.Name);
but what if you want to order dynamically by the property name ("Name") in run-time (from data storage source for example)
what would you do, do you use switch-case?
Nah, there's a much more better solution than this and it's 3~5 lines of code!
Lambda Expressions
We need the lambda expression to be replaced by a string parameter, fortunately it's easy building up a lambda expression by the property name and the object type.
Let's break down the lambda expression passed to OrderBy : x => x.Name
x is the parameter and it's of type T which get inferred in compile time from the invoked list.
Name is the member
so let's create them:
Parameter:
var param = Expression.Parameter(typeof(Foo), "p");
Member:
var member = Expression.Property(param, "Name");
then assemble the lambda expression:
var lambda = Expression.Lambda<Func<Foo, object>>(member, param);
lambda will only work on IQueryable because it's of type Expression<Func<Foo, object>>
to work on IEnumerable we need to compile it:
lambda.Compile();
the following is the complete code:
The implementation of OrderBy allows us to pass lambda expression in the form: x => x.Name
so to order list of students by name, you do the following:
var orderedStudents = allStudents.OrderBy(s => s.Name);
but what if you want to order dynamically by the property name ("Name") in run-time (from data storage source for example)
what would you do, do you use switch-case?
Nah, there's a much more better solution than this and it's 3~5 lines of code!
Lambda Expressions
We need the lambda expression to be replaced by a string parameter, fortunately it's easy building up a lambda expression by the property name and the object type.
Let's break down the lambda expression passed to OrderBy : x => x.Name
x is the parameter and it's of type T which get inferred in compile time from the invoked list.
Name is the member
so let's create them:
Parameter:
var param = Expression.Parameter(typeof(Foo), "p");
Member:
var member = Expression.Property(param, "Name");
then assemble the lambda expression:
var lambda = Expression.Lambda<Func<Foo, object>>(member, param);
lambda will only work on IQueryable because it's of type Expression<Func<Foo, object>>
to work on IEnumerable we need to compile it:
lambda.Compile();
the following is the complete code:
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.