Food obj = ...;
ILGenerator gen = (...).GetILGenerator();
gen.Emit( ?? obj ?? ); // replace this
gen.Emit(OpCodes.Call, typeof(Person).GetMethod("Eat"));
显然不可能干净地将obj推到评估堆栈上,但我对可能会损害的丑陋黑客持开放态度,例如便携性。 ModuleBuilder.DefineInitializedData允许在.sdata中存储System.Byte []。有什么想法吗?
编辑:生成的方法作为新程序集的一部分发出。
答案 0 :(得分:1)
object o = ...;
Func<object> sneaky = () => o;
gen.Emit(OpCodes.Call, sneaky.Method);
另外,请确保您不能将System.Linq.Expressions用于您的目的。以下是我之前和之后ANTLR项目中代码的一部分:
在。请注意,这里有一个错误(找不到关于它的邮件列表帖子)我没有找到,因为切换到“After”后将其更正为副作用。
private static Func<object, object> 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<object, object>)dm.CreateDelegate(typeof(Func<object, object>));
}
private static Func<object, object> 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<object, object>)dm.CreateDelegate(typeof(Func<object, object>));
}
后:
private static Func<object, object> BuildAccessor(MethodInfo method)
{
ParameterExpression obj = Expression.Parameter(typeof(object), "obj");
Expression<Func<object, object>> expr =
Expression.Lambda<Func<object, object>>(
Expression.Convert(
Expression.Call(
Expression.Convert(obj, method.DeclaringType),
method),
typeof(object)),
obj);
return expr.Compile();
}
private static Func<object, object> BuildAccessor(FieldInfo field)
{
ParameterExpression obj = Expression.Parameter(typeof(object), "obj");
Expression<Func<object, object>> expr =
Expression.Lambda<Func<object, object>>(
Expression.Convert(
Expression.Field(
Expression.Convert(obj, field.DeclaringType),
field),
typeof(object)),
obj);
return expr.Compile();
}
答案 1 :(得分:0)
我建议序列化你需要的对象,然后发出一个调用来从资源流中反序列化它(如果要经常访问它,可能会缓存它)。