用IL构造对象和调用方法

时间:2011-06-05 11:45:56

标签: c# reflection.emit il

我编写了以下程序,以便了解IL中的对象构造和方法调用,不幸的是它不会打印

  

你好吗

在控制台上。

你有什么想法吗?

下面给出了peverify的输出。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection.Emit;
using System.Reflection;
using System.IO;

namespace Research
{
    public class Program
    {
        public static void Main(string[] args)
        {
            AssemblyName name = 
                new AssemblyName(Path.GetFileNameWithoutExtension("Hello"));
            AssemblyBuilder asmb = 
                System.AppDomain.CurrentDomain.DefineDynamicAssembly(name, 
                                                    AssemblyBuilderAccess.Save);
            ModuleBuilder modb = asmb.DefineDynamicModule("Hello");
            TypeBuilder typeBuilder = modb.DefineType("Bar");
            MethodBuilder methb = 
                typeBuilder.DefineMethod("Me", MethodAttributes.Static, 
                                            typeof(void), System.Type.EmptyTypes);
            ILGenerator gen = methb.GetILGenerator();

            ConstructorInfo cil = typeof(Research.Dog).GetConstructor(new Type[] { });
            gen.Emit(OpCodes.Newobj, cil);
            gen.Emit(OpCodes.Call, typeof(Research.Dog).GetMethod("Bark"));
            gen.Emit(OpCodes.Ret);
        }
    }
    public class Dog
    {
        public void Bark()
        {
            Console.WriteLine("How are you doing");
        }
    }
}
  

C:\ TEMP \研究\研究\ BIN \推出> peverify   Research.exe

     

Microsoft(R).NET Framework PE   验证。版本4.0.30319.1   版权所有(c)Microsoft Corporation。   保留所有权利。

     

中的所有类和方法   Research.exe已验证。

     

C:\ TEMP \研究\研究\ BIN \推出>

1 个答案:

答案 0 :(得分:2)

您创建一个动态程序集,然后不执行任何操作。为什么要打印什么?此外,peverify在这里不会以任何方式帮助你,因为你没有验证你生成的程序集,你只是验证正在生成它的程序集。

您也不会调用typeBuilder.CreateType(),这是必要的,并且您的程序集未设置为无法运行。

如果您使用AssemblyBuilderAccess.RunAndSave并在方法的末尾添加以下代码,它将起作用(至少它适用于我):

var barType = typeBuilder.CreateType();
var meMethod = barType.GetMethod("Me", BindingFlags.Static | BindingFlags.NonPublic);
meMethod.Invoke(null, null);