It is relatively easy to create a lambda function that will return the value of a property from an object, even including deep properties ...
Func<Category, string> getCategoryName = new Func<Category, string>(c => c.Name);
and it can be called as follows:
string categoryName = getCategoryName(this.category);
But, given only the function obtained above (or the expression originally used to create the function), can anyone provide an easy way to create the opposite action ...
Action<Category, string> setCategoryName = new Action<Category, string>((c, s) => c.Name = s);
... which allows you to set the same property value as follows:
setCategoryName(this.category, "");
Note that I'm looking for a way to programmatically create an action from a function or expression - I hope that I showed that I already know how to create it manually.
I am open to answers that work in both .net 3.5 and 4.0.
Thanks.
UPDATE:
Perhaps it is not clear to me in my question, so let me try to demonstrate more clearly what I'm trying to do.
I have the following method (which I created for the purpose of this question) ...
void DoLambdaStuff<TObject, TValue>(TObject obj, Expression<Func<TObject, TValue>> expression) { Func<TObject, TValue> getValue = expression.Compile(); TValue stuff = getValue(obj); Expression<Action<TObject, TValue>> assignmentExpression = (o, v) => Expression<TObject>.Assign(expression, Expression.Constant(v, typeof(TValue))); Action<TObject, TValue> setValue = assignmentExpression.Compile(); setValue(obj, stuff); }
I'm looking for how to create an “assignment assignment” in code so that I can compile it into setValue? I believe this is due to Expression.Assign, but I just can't work out the right combination of parameters to complete the code.
The end result is the ability to call
Category category = *<get object from somewhere>*; this.DoLambdaStuff(category, c => c.Name);
and this, in turn, will create a getter and setter for the Name property of the Category object.
The above version compiles, but when I call setValue (), it results in an ArgumentException with the expression “Expression must be written”.
Thanks again.