将对象文字提供给ILGenerator

Food obj = ...; ILGenerator gen = (...).GetILGenerator(); gen.Emit( ?? obj ?? ); // replace this gen.Emit(OpCodes.Call, typeof(Person).GetMethod("Eat")); 

显然不可能干净地将obj推到评估堆栈上,但我对丑陋的黑客持开放态度,这可能会影响可移植性。 ModuleBuilder.DefineInitializedData允许在.sdata中存储System.Byte []。 有任何想法吗?

编辑:生成的方法作为新程序集的一部分发出。

 object o = ...; Func sneaky = () => o; gen.Emit(OpCodes.Call, sneaky.Method); 

另外,请确保您不能将System.Linq.Expressions用于您的目的。 以下是我之前和之后ANTLR项目中代码的一部分:

之前。 请注意,这里有一个错误(找不到关于它的邮件列表post)我没有找到,因为切换到“After”后将其更正为副作用。

 private static Func BuildAccessor(MethodInfo method) { DynamicMethod dm = new DynamicMethod(method.DeclaringType.Name + method.Name + "MethodAccessor", typeof(object), new Type[] { typeof(object) }, method.DeclaringType); var gen = dm.GetILGenerator(); if (!method.IsStatic) { gen.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); gen.Emit(System.Reflection.Emit.OpCodes.Castclass, method.DeclaringType); } if (method.IsVirtual && !method.IsFinal) gen.EmitCall(System.Reflection.Emit.OpCodes.Callvirt, method, null); else gen.EmitCall(System.Reflection.Emit.OpCodes.Call, method, null); if (method.ReturnType.IsValueType) gen.Emit(System.Reflection.Emit.OpCodes.Box, method.ReturnType); gen.Emit(System.Reflection.Emit.OpCodes.Ret); return (Func)dm.CreateDelegate(typeof(Func)); } private static Func BuildAccessor(FieldInfo field) { DynamicMethod dm = new DynamicMethod(field.DeclaringType.Name + field.Name + "FieldAccessor", typeof(object), new Type[] { typeof(object) }, field.DeclaringType); var gen = dm.GetILGenerator(); if (field.IsStatic) { gen.Emit(System.Reflection.Emit.OpCodes.Ldsfld, field); } else { gen.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); gen.Emit(System.Reflection.Emit.OpCodes.Castclass, field.DeclaringType); gen.Emit(System.Reflection.Emit.OpCodes.Ldfld, field); } if (field.FieldType.IsValueType) gen.Emit(System.Reflection.Emit.OpCodes.Box, field.FieldType); gen.Emit(System.Reflection.Emit.OpCodes.Ret); return (Func)dm.CreateDelegate(typeof(Func)); } 

后:

 private static Func BuildAccessor(MethodInfo method) { ParameterExpression obj = Expression.Parameter(typeof(object), "obj"); Expression> expr = Expression.Lambda>( Expression.Convert( Expression.Call( Expression.Convert(obj, method.DeclaringType), method), typeof(object)), obj); return expr.Compile(); } private static Func BuildAccessor(FieldInfo field) { ParameterExpression obj = Expression.Parameter(typeof(object), "obj"); Expression> expr = Expression.Lambda>( Expression.Convert( Expression.Field( Expression.Convert(obj, field.DeclaringType), field), typeof(object)), obj); return expr.Compile(); } 

我建议序列化您需要的对象,并发出调用以从资源流反序列化它(如果您要经常访问它,可能会缓存)。