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.
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:
- I will use it to pass the source element from/to where I will get/set the value.
- 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
- This kind of expression will help me to get/set a value from an Array type. (so far unidimensional arrays).
- I'll use this expression type along with
Item property to get/set values from a IDictionary<,>.
- Used aside with
ElementAt method to get values from IEnumerable<> types
And some reflection... (despite I don't like it)
- Item property from IDictionary<,>
Item property is the indexer for this kind of elements and it will allow me to have a string like "
- 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.
- 04/22/2013 - Added support to set a value to an
- 04/22/2013 - Added validation when trying to set a value to a