c# - reflection in the System.Reflection.Emit namespace - ModuleBuilder

本文介绍了如何利用System.Reflection.Emit命名空间中的ModuleBuilder类来创建动态模块。通过一个示例展示了从定义动态程序集到创建类型、字段及方法的全过程,并演示了如何使用ILGenerator生成中间语言。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

The namespace of System.Reflection.Emit is the rennovated namespace for reflection based APIs. In this topic, we are going to discuss the how to use the ModuleBuilder from this particular namespace. 

 

 

the original MSDN documentation on the ModuleBuilder is avaiable here in this page: Module Builder Class 

 

 

public class CodeGenerator
  {
    AssemblyBuilder myAssemblyBuilder;

    public CodeGenerator()
    {
      // Get the current application domain for the current thread
      AppDomain myCurrentDomain = AppDomain.CurrentDomain;

      AssemblyName myAssemblyName = new AssemblyName();
      myAssemblyName.Name = "TempAssembly";              // looks like we are creating the assemblies on the fly

      // Define a dynamic assembly in the current application domain.
      myAssemblyBuilder = myCurrentDomain.DefineDynamicAssembly(myAssemblyName, AssemblyBuilderAccess.Run); // indicate what kind of acces the generated assemblies is supposed to used!

      // now we have the Assembly, we can then create the module in this assembly
      ModuleBuilder myModuleBuilder = myAssemblyBuilder.DefineDynamicModule("TempModule");

      // Define a runtime class with specified name and attributes 
      TypeBuilder myTypeBuilder = myModuleBuilder.DefineType("TempClass", TypeAttributes.Public);

      // Add a Field, which is called "Greeting" to the class, with the specified attribute and type.
      FieldBuilder greetingField = myTypeBuilder.DefineField("Greeting", typeof(string), FieldAttributes.Public);

      Type[] myMethodArgs = { typeof(string) }; // type of the Method Args is defined as such

      // Add 'MyMethod' method to the class, with teh specified attributes and signature 
      MethodBuilder myMethod = myTypeBuilder.DefineMethod("MyMethod", MethodAttributes.Public, CallingConventions.Standard, null, myMethodArgs);

      ILGenerator methodIL = myMethod.GetILGenerator();
      methodIL.EmitWriteLine("In the method...");
      // the following code has the same effect as 
      //  anonymous_fun(string arg) { 
      //    GreetingField =  arg;
      //    return;
      //  }
      methodIL.Emit(OpCodes.Ldarg_0);                 // load this pointer
      methodIL.Emit(OpCodes.Ldarg_1);                 // load the first argument, which "value"
      methodIL.Emit(OpCodes.Stfld, greetingField);    // store the value of "value" to the GreetingField
      methodIL.Emit(OpCodes.Ret);                     // return from the call
      myTypeBuilder.CreateType();                     // Generate the code


    }
    public AssemblyBuilder MyAssembly
    {
      get
      {
        return this.myAssemblyBuilder;
      }
    }
  }

  public class TestClass
  {
    [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
    public static void Main()
    {
      CodeGenerator myCodeGenerator = new CodeGenerator();

      // Get the Assembly builder for 'myCodeGenerator' object.
      AssemblyBuilder myAssemblyBuilder = myCodeGenerator.MyAssembly;
      // Get the module builder for the above assembly builder object.
      ModuleBuilder myModuleBuidler = myAssemblyBuilder.GetDynamicModule("TempModule");

      // Display the fully qualified name of the moduel
      Console.WriteLine("The fully qualified name and path to this " + "module is :" + myModuleBuidler.FullyQualifiedName);

      // 
      Type myType = myModuleBuidler.GetType("TempClass");
      MethodInfo myMethodInfo = myType.GetMethod("MyMethod");

      // Get the token used to identify the method iwthin this module
      // SO be careful that the method does not return the MethodInfo, but rather return 
      // the method tokens
      MethodToken myMethodToken = myModuleBuidler.GetMethodToken(myMethodInfo);

      Console.WriteLine("Token used to identify the method of 'myType'" + "within the module is {0:x}", myMethodToken.Token);
      object[] args = { "Hello." };
      object myObject = Activator.CreateInstance(myType, null, null);
      myMethodInfo.Invoke(myObject, args);
    }
  }
 

 

As you can see:

 

 

  • there are different types of builder, e.g. ModuleBuilder, TypeBuilder,  FieldBuidler, MethodBuilder which build Module, Type,  Field or Method;
  • The various xxxBuilder class has the DefineXXX method to get a builder of subordinate constructs, e.g. ModuleBuilder.DefienType return TypeBuilder.
  • Each Builder is a subclass to XXXInfo, e.g. FiledBuilder is subclass to FieldInfo.
  • To generate the IL code, you may use the ILGenerator, and there is a bunch of Emit calls to generate the body of the method.
  • From each builder, you can query some adjunct construct, e.g. you can get ModuleBuilder from AssemblyBuilder...

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值