C# 在表达式树中指定实例成员字段

C# 在表达式树中指定实例成员字段,c#,expression-trees,C#,Expression Trees,我试图通过使类实例成为参数来修改。其主要思想是为类成员创建一个setter,不管它是字段还是属性。我在房地产方面很成功,但在油田方面却陷入了困境。这是原始代码的相关部分: public static Action<T> ToSetter<T>(Expression<Func<T>> expr) { var memberExpression = (MemberExpression)expr.Body; var instanceExp

我试图通过使类实例成为参数来修改。其主要思想是为类成员创建一个setter,不管它是字段还是属性。我在房地产方面很成功,但在油田方面却陷入了困境。这是原始代码的相关部分:

 public static Action<T> ToSetter<T>(Expression<Func<T>> expr) {
    var memberExpression = (MemberExpression)expr.Body;
    var instanceExpression = memberExpression.Expression;
    var parameter = Expression.Parameter(typeof(T));

    // assuming memberExpression.Member is FieldInfo;
    return Expression.Lambda<Action<T>>(Expression.Assign(memberExpression, parameter), parameter).Compile();        
}
public static Action to setter(表达式expr){
var memberExpression=(memberExpression)expr.Body;
var instanceExpression=memberExpression.Expression;
var参数=表达式参数(typeof(T));
//假设memberExpression.Member为FieldInfo;
返回Expression.Lambda(Expression.Assign(memberExpression,parameter),parameter.Compile();
}
应用程序:

 var setter= ToSetter<string>(() => myClient.WorkPhone);
 setter("12345");
var setter= ToSetter<Client,string>(c=> c.WorkPhone);
setter(myClient, "12345");
var setter=ToSetter(()=>myClient.WorkPhone);
塞特(“12345”);
这就是我想要的:

 public static Action<O,T> ToSetter<T,O>(Expression<Func<O,T>> expr) where O : class {
    var memberExpression = (MemberExpression)expr.Body;
    var instance = Expression.Parameter(typeof(O));
    var parameter = Expression.Parameter(typeof(T));

    // the following throws an InvalidOperationException exception:
    return Expression.Lambda<Action<O,T>>(
        Expression.Assign(memberExpression, parameter), parameter).Compile(); 
}
publicstaticaction-ToSetter(Expression-expr),其中O:class{
var memberExpression=(memberExpression)expr.Body;
var instance=Expression.Parameter(typeof(O));
var参数=表达式参数(typeof(T));
//以下操作引发InvalidOperationException异常:
返回表达式.Lambda(
Expression.Assign(memberExpression,parameter),parameter.Compile();
}
应用程序:

 var setter= ToSetter<string>(() => myClient.WorkPhone);
 setter("12345");
var setter= ToSetter<Client,string>(c=> c.WorkPhone);
setter(myClient, "12345");
var setter=ToSetter(c=>c.WorkPhone);
setter(我的客户,“12345”);

如何修改<代码>表达式?lambda(表达式?赋值(参数表达式,参数),实例,参数)?编译()/>代码>考虑类的实例<代码> o < /代码>?

    // Example usage: ToSetter<MyEntity, string>(c => c.FirstName)
    public static Action<TEntity, TResult> ToSetter<TEntity, TResult>(Expression<Func<TEntity, TResult>> expr)
    {
        // This will be `c.FirstName`
        var memberExpression = (MemberExpression)expr.Body;
        // This will be `c`
        var instanceParameter = (ParameterExpression)memberExpression.Expression;
        // New parameter for passing value named `value`
        var valueParameter = Expression.Parameter(typeof(TResult), "value");

        // Construct `(c, value) => c.FirstName = value`
        return Expression.Lambda<Action<TEntity, TResult>>(
            Expression.Assign(memberExpression, valueParameter), // c.FirstName = value
            instanceParameter, // c
            valueParameter // value
        ).Compile();        
    }
//示例用法:ToSetter(c=>c.FirstName)
公共静态作用到记录器(表达式表达式)
{
//这将是'c.FirstName'`
var memberExpression=(memberExpression)expr.Body;
//这将是'c'`
var instanceParameter=(ParameterExpression)memberExpression.Expression;
//用于传递名为`value'的值的新参数`
var valueParameter=表达式参数(typeof(TResult),“value”);
//构造`(c,value)=>c.FirstName=value`
返回表达式.Lambda(
Expression.Assign(memberExpression,valueParameter),//c.FirstName=value
instanceParameter,//c
value参数//值
).Compile();
}

您缺少的是
Lambda
调用的第二个参数。另外,
memberExpression
在原始lambda中有一些参数,它必须与新lambda中的参数相同。

是否需要构建一个设置值的lambda?如果没有,在知道所涉及成员的名称后,您是否可以使用反射来获取成员并设置其值?@WiktorZychla:setter可能经常使用,这就是为什么我更喜欢基于表达式树的解决方案而不是基于反射的解决方案。MarkusParker:您看过这个问题吗@jgauffin:据我所知,这个问题是关于财产的,我可以处理。我对字段有问题。