This would be very simple if I were able to assign via a Lambda expression (below)
//An expression tree cannot contain an assignment operator
Expression<Func<ComplexObj, object>> expression = obj => obj.Contacts[0].FirstName = "Tim";
This code above is invalid due to the assignment operator. I need to pass a lambda expression in order to identify the property in the complex object that needs to be set. In some cases the complex object has List and therefor duplicate object types and names which is why I need the lambda to explicitly reference the field in the object to be updated.
I am able to retrieve the value using the following, no problem. But I am not sure how to use this same logic to set the value, I came across Expression.Assign and believe this may be the solution.
Expression<Func<ComplexObj, object>> expression = obj => obj.Contacts[0].FirstName;
var result = FindByProperty(expression);
public static string FindByProperty(Expression<Func<Contract, object>> propertyRefExpr)
{
ComplexObj obj = new ComplexObj();
Contact myContact = new Contact();
myContact.FirstName = "Allen";
obj.Contacts = new List<Contact>{myContact};
return propertyRefExpr.Compile().Invoke(obj);
}
Update:
"passing a property assignment to a method as an expression tree..."
Using the SetValue method with ParentTypeA, Value will not work. (below code)
Expression<Func<ComplexObj, object>> expression = obj => obj.Contacts[0].FirstName;
obj.AssignNewValue(expression, firstName);
public static void AssignNewValue(this ComplexObj obj, Expression<Func<ComplexObj, object>> expression, object value)
{
var propertyInfo = (PropertyInfo)((MemberExpression)expression.Body).Member;
propertyInfo.SetValue(obj, value, null);
}
I ended up using the following solution. Cheers
The linked-to question is probably the "right" answer, but just for the sake of completeness, you could do something more like this...it does follow the "tell, don't ask" methodology a bit better, although I can't say I like the implementation...