Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 修改方法的IL代码的更好方法是什么?_C#_Code Generation_Reflection.emit - Fatal编程技术网

C# 修改方法的IL代码的更好方法是什么?

C# 修改方法的IL代码的更好方法是什么?,c#,code-generation,reflection.emit,C#,Code Generation,Reflection.emit,我需要将方法A()中的call指令从this.B()替换为this.C()。现在我用来获取方法A()的IL指令,然后替换call指令,然后使用IL生成器手动发出所有指令。 注意:该助手有一个nuget- 代码的一部分,用于演示我需要的内容: var emitter = methodBuilder.GetILGenerator(); foreach (var cmd in baseMethodInfo.GetInstructions()) { if (cmd.Operand == null

我需要将方法
A()
中的
call
指令从
this.B()
替换为
this.C()
。现在我用来获取方法
A()
的IL指令,然后替换
call
指令,然后使用IL生成器手动发出所有指令。 注意:该助手有一个nuget-

代码的一部分,用于演示我需要的内容:

var emitter = methodBuilder.GetILGenerator();
foreach (var cmd in baseMethodInfo.GetInstructions())
{
    if (cmd.Operand == null)
        emitter.Emit(cmd.OpCode);
    else
    {
        switch (cmd.OpCode.OperandType)
        {
            case OperandType.InlineMethod:
            {
                var currentMethodInfo = cmd.Operand as MethodInfo;
                //check that it's this.B() and get this.C() then
                var methodToReplace = installedMethods.SingleOrDefault(m => m.MethodInfo == currentMethodInfo);
                if (methodToReplace != null)
                    emitter.EmitCall(cmd.OpCode, methodToReplace.MethodBuilder, null);
                else
                    emitter.EmitCall(cmd.OpCode, currentMethodInfo, null);
                break;
            }
            ...
        }
    }
}

但我想有人已经实现了类似的东西,我想使用它,因为它很可能是一种更好、更安全的方式。我知道Mono.Cecil提供了替换指令的功能,但正如我所知,它只适用于
asembly加载时间
,但我需要
运行时

使用Cecil进行替换是最简单的方法。正如svick所写,即使需要替换的方法的信息在运行时出现(当然,只要该方法满足您的性能要求),您也可以这样做


但是如果您想检查其他选项,请检查。

使用Cecil进行检查是最简单的方法。正如svick所写,即使需要替换的方法的信息在运行时出现(当然,只要该方法满足您的性能要求),您也可以这样做


但是如果您想检查其他选项,请检查。

为什么需要“运行时”?看起来你正在创建一个新的方法,难道你不能使用Cecil创建一个新的程序集,其中只包含你需要的方法吗?不幸的是,我得到了在运行时应该替换哪些方法的信息<例如,code>this.B()和
this.C()
。为什么会出现这个问题?您可以在运行时创建并加载程序集。可能的性能问题。在我替换我将需要生成的代码的每个地方(在不同的方法中相同),保存并加载程序集。使用reflection.emit,我可以声明单个程序集。但是我没有考虑建议的方法。我可以试一下,测试一下性能。谢谢。程序集加载时间是运行时。如果您试图在加载程序集后执行此操作,则很可能太晚,必须在即时编译器从IL生成机器代码之前执行此操作。您为什么需要“运行时”?看起来你正在创建一个新的方法,难道你不能使用Cecil创建一个新的程序集,其中只包含你需要的方法吗?不幸的是,我得到了在运行时应该替换哪些方法的信息<例如,code>this.B()和
this.C()
。为什么会出现这个问题?您可以在运行时创建并加载程序集。可能的性能问题。在我替换我将需要生成的代码的每个地方(在不同的方法中相同),保存并加载程序集。使用reflection.emit,我可以声明单个程序集。但是我没有考虑建议的方法。我可以试一下,测试一下性能。谢谢。程序集加载时间是运行时。如果您试图在加载程序集后执行此操作,则很可能太晚,必须在即时编译器从IL生成机器代码之前执行此操作。