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);
}
Assignment expression are written with a new notation (:=) . This operator is often called the walrus operator as it resembles the eyes and tusks of a walrus on its side. The assignment expression allows you to assign True to walrus , and immediately print the value.
JavaScript uses the = operator to assign a value to a variable or property. For example: i = 0 // Set the variable i to 0. o .
Only expression trees that represent lambda expressions can be executed. Expression trees that represent lambda expressions are of type LambdaExpression or Expression<TDelegate>. To execute these expression trees, call the Compile method to create an executable delegate, and then invoke the delegate.
I ended up using the following solution. Cheers
ComplexObj obj = new ComplexObj();
Expression<Func<ComplexObj, object>> expression = obj => obj.Contacts[index].FirstName;
obj.AssignNewValue(expression, firstName);
public static void AssignNewValue(this ComplexObj obj, Expression<Func<ComplexObj, object>> expression, object value)
{
ParameterExpression valueParameterExpression = Expression.Parameter(typeof(object));
Expression targetExpression = expression.Body is UnaryExpression ? ((UnaryExpression)expression.Body).Operand : expression.Body;
var newValue = Expression.Parameter(expression.Body.Type);
var assign = Expression.Lambda<Action<ComplexObj, object>>
(
Expression.Assign(targetExpression, Expression.Convert(valueParameterExpression, targetExpression.Type)),
expression.Parameters.Single(),
valueParameterExpression
);
assign.Compile().Invoke(obj, value);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With