一般来说,如何将ilasm语法转换为Reflection.Emit调用?

时间:2010-06-13 18:05:23

标签: .net reflection.emit cil ildasm

我正在编写一个特殊用途的迷你编译器,我经常查看反汇编的CIL来弄清楚如何做事。但是,如何将反汇编代码转换为Reflection.Emit调用通常并不明显。是否存在参考手册或进行此翻译的任何其他信息来源?

编辑:是的,将操作码映射到ILGenerator非常简单;我在谈论所有其他的东西,比如.directives和属性。例如,你如何找到如何编写像Dictionary<TKey,TValue>这样的Reflection.Emit等价物?

.class public auto ansi serializable beforefieldinit Dictionary<TKey, TValue>
    extends System.Object
    implements System.Collections.Generic.IDictionary`2<!TKey, !TValue>,
    System.Collections.Generic.ICollection`1<valuetype 
        System.Collections.Generic.KeyValuePair`2<!TKey, !TValue>>, 
    ...
{
    .custom instance void System.Diagnostics.DebuggerDisplayAttribute::
        .ctor(string) = { string('Count = {Count}') }

    .method public hidebysig newslot virtual final instance bool TryGetValue
        (!TKey key, [out] !TValue& 'value') cil managed
    {
        .maxstack 3
        .locals init ([0] int32 num)
        ...

或者“param”指令怎么样?

// public static void SayHello(string s = "Hello World!")
.method public hidebysig static void SayHello([opt] string s) cil managed
{
    .param [1] = "Hello World!"

3 个答案:

答案 0 :(得分:4)

为此目的,我会使用EmitHelper componentBLToolkit。它提供了一个类似IL代码的流畅API,包装了Reflection.Emit。从链接文章中提取的示例:

EmitHelper emit = new AssemblyBuilderHelper("HelloWorld.dll")
    .DefineType  ("Hello", typeof(object), typeof(IHello))
    .DefineMethod(typeof(IHello).GetMethod("SayHello"))
    .Emitter;
emit
    // string.Format("Hello, {0}!", toWhom)
    //
    .ldstr   ("Hello, {0}!")
    .ldarg_1
    .call    (typeof(string), "Format", typeof(string), typeof(object))

    // Console.WriteLine("Hello, World!");
    //
    .call    (typeof(Console), "WriteLine", typeof(string))
    .ret();

Type type = emit.Method.Type.Create();

答案 1 :(得分:1)

您正在查看IL的System.Collections.Generic.Dictionary&lt;&gt;类。 “Dictionary”类名是传递给ModuleBuilder.DefineType()的字符串。

.param属性在C#版本4或VB.NET中为具有默认值的参数生成。您可以使用从MethodBuilder.DefineParameter()返回的ParameterBuilder进行设置。使用SetConstant()方法。

答案 2 :(得分:1)

由于没有人可以回答这个问题,因此我得出的结论是,没有任何文档可以显示ilasm语法和Reflection.Emit调用之间的关系。

作为旁注,我发现使用RunSharp在运行时创建代码通常比使用Reflection.Emit更好。如果我有时间,我会尝试找出Cecil的新版本。