Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Dynamic Lambda Expression Compiler

0.00/5 (No votes)
9 Apr 2014 1  
Did you ever dreamed about compiling a string like x => x.Property.Array[3].Property and actually get a value from it?

Introduction

I faced the problem of getting/setting values dynamically to/from an object and the principal issue is that I will have a string with the instruction as a lambda expression which will need to be compiled at runtime.

For instance Set 'Fernando' to the property Name of the object Person would be something like: p => p.Name = "Fernando".

I can also set a dynamic value (something I will get from another object) to the property or get it from an array/IEnumerable/IDictionary, have it on an inner property...

At the end this solutions needs to get/set values form any part of the object graph no matter where is it.

Background

Reflection was my first option, but is know that it is slow, so Expression Trees should (must) be the solution.

As you will see, I will need few Expression to solve this problem:

  • ParameterExpression
    • I will use it to pass the source element from/to where I will get/set the value.
  • ConstantExpression
    • To set a value we need it to be a constant (despite from where it will come).
  • BinaryExpression (Assign)
    • Well... I let it to your imagination :P
    • ArrayIndex
      • This kind of expression will help me to get/set a value from an Array type. (so far unidimensional arrays).
    • IndexExpression
      • I'll use this expression type along with Item property to get/set values from a IDictionary<,>.
    • MethodCallExpression
      • Used aside with ElementAt method to get values from IEnumerable<> types

    And some reflection... (despite I don't like it)

    • Item property from IDictionary<,>
      • this Item property is the indexer for this kind of elements and it will allow me to have a string like "element.Dictionary[elementKey]".
    • ElementAt method from Enumerable extensions.
      • by using ElementAt method I can access an Enumerable by index.

    Using the code

    As it is implemented as helper methods to the dynamic type (I've chosen this rather than object because I needed to so some interop as well) the use is of it very simple.

    var testElement = new 
              {
                  PropertyToChange = "oldValue", 
                  InnerTestElement = new 
    
                                         {
                                             TestProperty = "prop2"
                                         }
              }; 
    DynamicLinqExtensions.SetValueToExpression(testElement, "testElement.TestProperty", "prop1");
    
    Assert.AreEqual("prop1", (string)DynamicLinqExtensions.GetValueFromExpression(testElement, "TestProperty"));
    Assert.AreEqual("prop2", (string)DynamicLinqExtensions.GetValueFromExpression(testElement, "InnerTestElement.TestProperty"));

    Points of Interest

    I think is a nice project to meet Expression Trees.

    History

    • 04/22/2013 - Added support to set a value to an IDictionary<,> type.
    • 04/22/2013 - Added validation when trying to set a value to a IEnumerable<> type.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here