.NET Core - ILGenerator.Emit (一)

Official website address: https://docs.microsoft.com/zh-cn/dotnet/api/system.reflection.emit.ilgenerator.emit?view=netcore-3.1

First, know Emit

  

   Emit manner using methods may be written in C # code and generate IL code execution.

Second, simple to use

   Example: create an assembly, create a module, create a class, create a constructor, create and invoke methods

static void Main(string[] args)
{
    // -- 创建程序集
    AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("Example.Generator"), AssemblyBuilderAccess.RunAndCollect);
    // -- 创建模块
    ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("Generators");
    // -- 创建 Generator 类
    TypeBuilder typeBuilder = moduleBuilder.DefineType("Generator");

    // -- 创建构造函数
    ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes);
    //   - filling the constructor of IL codes need to perform 
    the ILGenerator constructGenerator = constructorBuilder.GetILGenerator ();
     // - definition of a string 
    constructGenerator.Emit (OpCodes.Ldstr, "Building the logic code constructor by the Emit " );
     / / - call Console.WriteLine () output words 
    constructGenerator.Emit (OpCodes.Call, typeof (Console) .GetMethod ( " the WriteLine " , new new the Type [] { typeof ( String )}));
     // - return 
    constructGenerator. EMIT (OpCodes.Ret);
     // - create a method 
    MethodBuilder method = typeBuilder.DefineMethod (" The Start " , MethodAttributes.Public, typeof ( void ), new new the Type [] { typeof ( String )});
     //   - declare a method parameter name name 
    method.DefineParameter ( 0 , ParameterAttributes.None, " name " ) ;
     //   - method of preparation of IL code inside 
    the ILGenerator methodGenerator = method.GetILGenerator ();
     // - incoming print parameter name 
    methodGenerator.Emit (OpCodes.Ldarg_1); 
    methodGenerator.Emit (OpCodes.Call, typeof (Console ) .GetMethod ( " the WriteLine", new Type[] { typeof(string) }));
    methodGenerator.Emit(OpCodes.Ret);
    // -- 创建实例
    Type instance = typeBuilder.CreateType();
    object proxy = Activator.CreateInstance(instance);
// -- 调用 MethodInfo methodInfo
= proxy.GetType().GetMethod("Start"); methodInfo.Invoke(proxy, new string[] { "Hello Elson" }); Console.ReadKey(); }

 Third, emphasis

constructGenerator.Emit (OpCodes.Ldstr, " Building the logic code constructor by the Emit " ); 
constructGenerator.Emit (OpCodes.Call, typeof (Console) .GetMethod ( " the WriteLine " , new new the Type [] { typeof ( String )} )); 
constructGenerator.Emit (OpCodes.Ret);

OpCodes.Ldstr:Pushes a new object reference to a string literal stored in the metadata.

  Can be understood as: String A = "Content"

OpCodes.Call:Calls the method indicated by the passed method descriptor.

   It can be understood as: call the method as described above.

         The way we call the original method is: Console.WriteLine ( "Content"); and using  Emit  calls the method requires a description of the method: class type, method name, parameter types.

OpCodes.Ret:Returns from the current method, pushing a return value (if present) from the callee's evaluation stack onto the caller's evaluation stack.

   It can be understood as: return value

// - define a method: Method name, access level, characteristic method, the return type, argument types
MethodBuilder = typeBuilder.DefineMethod Method ( " the Start " , MethodAttributes.Public, typeof ( void ), new new the Type [] { typeof ( String )}); // - declare a method parameters: parameter index, characteristic parameter, the parameter name method.DefineParameter ( 0 , ParameterAttributes.None, " name " ); the ILGenerator methodGenerator = method.GetILGenerator (); methodGenerator.Emit ( OpCodes.Ldarg_1); methodGenerator.Emit (OpCodes.Call, typeof (Console) .GetMethod ( " the WriteLine", new Type[] { typeof(string) })); methodGenerator.Emit(OpCodes.Ret);

OpCodes.Ldarg_1:Loads the argument at index 1 onto the evaluation stack.

   Gets the parameters on the parameter index 1 position, if not a static method, OpCodes.Ldarg_0 acquisition is the this , the current object instance

class Example
{
    public void GetContent(string content)
    {
        //Codes.Ldarg_0 = Example
        var  _this = this;  
        //Codes.Ldarg_1 = content
        var param = content
    }  
}

IV Conclusion

   Everybody is welcome to correct me, common learning progress!

谦良恭卑,信诚实至;生活不易,共勉同求。

 

Guess you like

Origin www.cnblogs.com/elsonww/p/12288003.html