Click here to Skip to main content
Click here to Skip to main content
Go to top

Dynamic Lambda Expression Compiler

, 9 Apr 2014
Rate this:
Please Sign up or sign in to vote.
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Fernando Callejon

Argentina Argentina
http://ar.linkedin.com/in/fcallejon

Comments and Discussions

 
QuestionNice article PinmemberWolfstein22-Apr-13 6:08 
+1 for the way to go...

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140916.1 | Last Updated 9 Apr 2014
Article Copyright 2013 by Fernando Callejon
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid