c# - 如何在 C# 表达式树中设置字段值?

标签 c# lambda expression-trees

给定:

FieldInfo field = <some valid string field on type T>;
ParameterExpression targetExp = Expression.Parameter(typeof(T), "target");
ParameterExpression valueExp = Expression.Parameter(typeof(string), "value");

如何编译 lambda 表达式以将“目标”参数上的字段设置为“值”?

最佳答案

.Net 4.0:现在有了 Expression.Assign,这很容易做到:

FieldInfo field = typeof(T).GetField("fieldName");
ParameterExpression targetExp = Expression.Parameter(typeof(T), "target");
ParameterExpression valueExp = Expression.Parameter(typeof(string), "value");

// Expression.Property can be used here as well
MemberExpression fieldExp = Expression.Field(targetExp, field);
BinaryExpression assignExp = Expression.Assign(fieldExp, valueExp);

var setter = Expression.Lambda<Action<T, string>>
    (assignExp, targetExp, valueExp).Compile();

setter(subject, "new value");

.Net 3.5:你不能,你必须改用 System.Reflection.Emit:

class Program
{
    class MyObject
    {
        public int MyField;
    }

    static Action<T,TValue> MakeSetter<T,TValue>(FieldInfo field)
    {
        DynamicMethod m = new DynamicMethod(
            "setter", typeof(void), new Type[] { typeof(T), typeof(TValue) }, typeof(Program));
        ILGenerator cg = m.GetILGenerator();

        // arg0.<field> = arg1
        cg.Emit(OpCodes.Ldarg_0);
        cg.Emit(OpCodes.Ldarg_1);
        cg.Emit(OpCodes.Stfld, field);
        cg.Emit(OpCodes.Ret);

        return (Action<T,TValue>) m.CreateDelegate(typeof(Action<T,TValue>));
    }

    static void Main()
    {
        FieldInfo f = typeof(MyObject).GetField("MyField");

        Action<MyObject,int> setter = MakeSetter<MyObject,int>(f);

        var obj = new MyObject();
        obj.MyField = 10;

        setter(obj, 42);

        Console.WriteLine(obj.MyField);
        Console.ReadLine();
    }
}

关于c# - 如何在 C# 表达式树中设置字段值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/321650/

相关文章:

c# - 为多级表达式生成 Expression<Func<TEntity, bool>>

c# - 如何处理在 RichTextBox 中单击超链接的事件

lambda - 根本没有调用 lambda 函数中的代码

c++ - 为什么 lambda 的大小为 1 个字节?

.net - 编译器通过位移操作将按位 AND 添加到表达式树中

c# - 继承时的表达式推断

c# - SQL Server 插入

c# - 作为计划任务运行 C# 应用程序

c# - 通过单击 ListView (Xamarin.Forms) 中的按钮获取当前项

boost - c++0x lambdas,不让我作为函数 ptr 传递