5

私は次の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でそれ以上を取得するにはどうすればよいですか?

4

1 に答える 1

4

私が何かをしたいのなら、私は通常、期待されるコードMono.Cecilでクラス/メソッドを作成します。C#次に、を使用して検査し(リリースモードで実行していることを確認します)Mono.Cecil、再作成します。

したがって、とパラメータが必要MethodDefinitionになります。名前:「f」nameattributesreturnType

メソッドの属性は次のようになります。Mono.Cecil.MethodAttributes.FamANDAssem | Mono.Cecil.MethodAttributes.Family | Mono.Cecil.MethodAttributes.Static | Mono.Cecil.MethodAttributes.HideBySig

そして、戻り型(としての型Mono.Cecil.TypeReferenceSystem.Double

パラメータに関しては、2つParameterDefinition追加できますtarget.Parameters.Add()

パラメータの1つにデフォルト値があるため、その属性は次のように設定する必要がMono.Cecil.ParameterAttributes.Optional | Mono.Cecil.ParameterAttributes.HasDefault あります(あなたの場合)Constant1.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、それぞれのアセンブリにを注入/保存します。

私のアセンブリインスペクターコードは次のようになります。

 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());
                        }
                    }
                }
            }
        }
于 2012-10-12T09:06:53.213 に答える