gpt4 book ai didi

c# - 带有可选参数的发射函数

转载 作者:太空狗 更新时间:2023-10-29 23:24:46 25 4
gpt4 key购买 nike

我有以下 C# 代码:

public static double f(double x1, double x2 = 1)
{
return x1 * x2;
}

这是 IL 代码 (ILSpy):

.method public hidebysig static 
float64 f (
float64 x1,
[opt] float64 x2
) cil managed
{
.param [2] = float64(1)
// Method begins at RVA 0x20c6
// Code size 4 (0x4)
.maxstack 8

IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: mul
IL_0003: ret
} // end of method A::f

如何使用 System.Reflection.Emit 或更好地使用 Mono.Cecil

最佳答案

如果我想用 Mono.Cecil 做一些事情,我通常会使用预期的代码在 C# 中创建一个类/方法。然后,我使用 Mono.Cecil 检查它(确保您在 Release 模式下运行它)并重新创建它。

所以您需要一个带有nameattributesreturnType 参数的MethodDefinition。名字:“f”

您的方法的属性为:Mono.Cecil.MethodAttributes.FamANDAssem | Mono.Cecil.MethodAttributes.系列 | Mono.Cecil.MethodAttributes.静态 | Mono.Cecil.MethodAttributes.HideBySig

返回类型(Mono.Cecil.TypeReference 类型为 System.Double )

至于参数,有两个ParameterDefinition可以用target.Parameters.Add()添加

您的其中一个参数具有默认值,因此其属性必须是 Mono.Cecil.ParameterAttributes.Optional | Mono.Cecil.ParameterAttributes.HasDefault 及其 Constant 设置为 1.0(在您的情况下)

现在是方法体:

target.Body.GetILProcessor();  // target is your `MethodDefinition` object.

检查来自target.Body.Instructions 的指令后,我们看到以下代码:

IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: mul
IL_0003: stloc.0
IL_0004: br.s IL_0007
IL_0005: ldloc.0
IL_0007: ret

所以只需按正确的顺序添加代码

 processor.Append(OpCodes.Ldarg_0);

之后,将您的 MethodDefinition 注入(inject)/保存到相应的程序集。

我的汇编检查器代码看起来像这样:

 private static void EnumerateAssembly(AssemblyDefinition assembly)
{
foreach (var module in assembly.Modules)
{
foreach (var type in module.GetAllTypes())
{
foreach (var field in type.Fields)
{
Debug.Print(field.ToString());
}
foreach (var method in type.Methods)
{
Debug.Print(method.ToString());
foreach (var instruction in method.Body.Instructions)
{
Debug.Print(instruction.ToString());
}
}
}
}
}

关于c# - 带有可选参数的发射函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12855201/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com