鉴于:
FieldInfo field =; ParameterExpression targetExp = Expression.Parameter(typeof(T), "target"); ParameterExpression valueExp = Expression.Parameter(typeof(string), "value");
如何编译lambda表达式以将"target"参数上的字段设置为"value"?
.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> (assignExp, targetExp, valueExp).Compile(); setter(subject, "new value");
.Net 3.5:你不能,你必须使用System.Reflection.Emit代替:
class Program { class MyObject { public int MyField; } static ActionMakeSetter (FieldInfo field) { DynamicMethod m = new DynamicMethod( "setter", typeof(void), new Type[] { typeof(T), typeof(TValue) }, typeof(Program)); ILGenerator cg = m.GetILGenerator(); // arg0. = arg1 cg.Emit(OpCodes.Ldarg_0); cg.Emit(OpCodes.Ldarg_1); cg.Emit(OpCodes.Stfld, field); cg.Emit(OpCodes.Ret); return (Action ) m.CreateDelegate(typeof(Action )); } static void Main() { FieldInfo f = typeof(MyObject).GetField("MyField"); Action setter = MakeSetter (f); var obj = new MyObject(); obj.MyField = 10; setter(obj, 42); Console.WriteLine(obj.MyField); Console.ReadLine(); } }
如已经讨论的那样,设置字段是有问题的.你可以(在3.5中)单个方法,例如属性设置器 - 但只能间接地.这得到4.0要容易得多,因为讨论在这里.但是,如果您实际拥有属性(而不是字段),则可以使用以下方法执行以下操作Delegate.CreateDelegate
:
using System; using System.Reflection; public class Foo { public int Bar { get; set; } } static class Program { static void Main() { MethodInfo method = typeof(Foo).GetProperty("Bar").GetSetMethod(); Actionsetter = (Action ) Delegate.CreateDelegate(typeof(Action ), method); Foo foo = new Foo(); setter(foo, 12); Console.WriteLine(foo.Bar); } }
private static Action