如何通过表达式分配值? [英] How to assign a value via Expression?

查看:54
本文介绍了如何通过表达式分配值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我能够通过Lambda表达式(如下)进行赋值,这将非常简单

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";

由于赋值运算符,上面的代码无效.我需要传递一个lambda表达式,以便识别需要设置的复杂对象中的属性.在某些情况下,复杂对象具有List,并因此具有重复的对象类型和名称,这就是为什么我需要lambda显式引用要更新的对象中的字段的原因.

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.

我可以使用以下方法检索值,没问题.但是我不确定如何使用相同的逻辑来设置值,我遇到了Expression.Assign,并相信这可能是解决方案.

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);
}

更新:

将属性分配作为表达式树传递给方法..."

"passing a property assignment to a method as an expression tree..."

将SetValue方法与ParentTypeA一起使用时,Value将不起作用.(下面的代码)

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

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);
}

这篇关于如何通过表达式分配值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆