0

我知道如何通过注入 IL 来创建动态方法,比如 a * 2;

但是我想像 a * b 一样,其中 b 是常数。

考虑一下。

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 或其他。

我的问题是如何将 b 值作为常量嵌入到 IL 中。

这是非常重要的区别——我不想计算 var a * var b。我想(例如,如果 b == 2 在运行时)创建执行 * 2 的 IL。

我有理由这样做。如果您按照所写的方式回答问题。谢谢你。

编辑。这是我在你的帮助下可以写的。请说说你的看法

    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>));
    }
4

2 回答 2

3

你想要ldc.i4操作码。

这会将一个 int 加载到堆栈上,然后可以跟一个mul.

你可以像这样使用它:

ilGen.Emit(OpCodes.Ldc_I4, b);

顺便说一句,您实际上并不需要在这里从 IL 构建方法。这种方法也可以:

Func<int, int> CreateDynMethod(int b)
{
    return a => a * b;
}
于 2012-06-13T21:24:31.220 回答
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/h3c68sh6http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.ldc_i4

于 2012-06-13T21:24:51.843 回答