我知道如何通过注入IL来创建一个动态方法,例如a * 2;
但是我希望它像a * b,其中b是consntant。
考虑一下。
int b = SomeClassInstance.Multiplier;
Func<int,int> MultA = CreateDynMethod(b);
for(int i = 0; i < 1000; i++)
{
int a = GetValueSomewhere();
int result = MultA(a);
Console.WriteLine(result);
}
参见.. b对于所有1000次迭代都是相同的。但是我不知道它会是什么。 0 1 2或其他什么。
我的问题是如何将IL中的b值作为常量嵌入。
这是非常重要的区别 - 我不希望计算var a * var b。 我想(如果例如b == 2在运行时)创建IL,它会执行* 2.
我有理由这样做。如果你回答问题,请回答。谢谢。
修改。这是我可以在你的帮助下写的。请告诉您的想法
static Func<int, int> IL_EmbedConst(int b)
{
var method = new DynamicMethod("EmbedConst", typeof(int), new[] { typeof(int) } );
var il = method.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldc_I4, b);
il.Emit(OpCodes.Mul);
il.Emit(OpCodes.Ret);
return (Func<int, int>)method.CreateDelegate(typeof(Func<int, int>));
}
答案 0 :(得分:3)
您需要ldc.i4
操作码。
这会将一个int加载到堆栈上,然后可以跟一个mul
。
您可以像这样使用它:
ilGen.Emit(OpCodes.Ldc_I4, b);
顺便说一下,你真的不需要在这里用IL构建方法。这种方法也可以使用:
Func<int, int> CreateDynMethod(int b)
{
return a => a * b;
}
答案 1 :(得分:1)
您可能想要发出类似
的内容 ldarg.1
ldc.i4 2
mul
ret
您可以使用
发出第二行 il.Emit(OpCodes.Ldc_I4, 2);
或者,为了清楚起见:
int b = 2;
il.Emit(OpCodes.Ldc_I4, b);
见http://msdn.microsoft.com/en-us/library/h3c68sh6 和http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.ldc_i4