• MSIL实用指南-字段的加载和保存


    字段有静态字段和非静态字段之分,它们的加载保存指令也是不一样的,并且非静态字段要生成this。

    静态字段的加载
    加载静态字段的指令是Ldsfld。
    ilGenerator.Emit(OpCodes.Ldsfld, <FieldBuilder>);
    实际例子

    ilGenerator.Emit(OpCodes.Ldsfld, areaFieldBuilder);
    ilGenerator.Emit(OpCodes.Call, writeStringLineMethod);


    静态字段的保存
    保存静态字段的指令是Stsfld。
    ilGenerator.Emit(OpCodes.Stsfld, <FieldBuilder>);
    实际例子

    ilGenerator.Emit(OpCodes.Ldstr,"New York");
    ilGenerator.Emit(OpCodes.Stsfld, areaFieldBuilder);


    实例字段的加载
    加载静态字段的指令是Ldsfld,必须要在第一步生成Ldarg_0指令。
    ilGenerator.Emit(OpCodes.Ldsfld, <FieldBuilder>);
    实际例子

    ilGenerator.Emit(OpCodes.Ldarg_0);//生成this
    ilGenerator.Emit(OpCodes.Ldfld, areaFieldBuilder);
    ilGenerator.Emit(OpCodes.Call, writeStringLineMethod);


    实例字段的保存
    保存静态字段的指令是Stsfld,必须要在第一步生成Ldarg_0指令。
    ilGenerator.Emit(OpCodes.Stsfld, <FieldBuilder>);
    实际例子

    ilGenerator.Emit(OpCodes.Ldarg_0);//生成this
    ilGenerator.Emit(OpCodes.Ldstr, "Tom");
    ilGenerator.Emit(OpCodes.Stfld, nameFieldBuilder);

    一个完整的程序如下

    using System;
    using System.Reflection;
    using System.Reflection.Emit;
    
    namespace LX1_ILDemo
    {
        class Demo09_FieldLoadStorm
        {
            static string binaryName = "Demo09_FieldLoadStorm.dll";
            static string namespaceName = "LX1_ILDemo";
            static string typeName = "FieldLoadStorm";
    
            static AssemblyBuilder assemblyBuilder;
            static ModuleBuilder moduleBuilder;
            static TypeBuilder typeBuilder;
            static MethodBuilder testMethod;
            static ILGenerator ilGenerator;
    
            static void Emit_IL()
            {
                /* protected string Area; */
                FieldBuilder areaFieldBuilder = typeBuilder.DefineField("Area", typeof(string),
                    FieldAttributes.Public | FieldAttributes.Static);
    
                /* private string Name; */
                FieldBuilder nameFieldBuilder = typeBuilder.DefineField("Name", typeof(string), FieldAttributes.Public);
    
                testMethod = typeBuilder.DefineMethod("Test", MethodAttributes.Public, typeof(void), new Type[] { });
                ilGenerator = testMethod.GetILGenerator();
    
                MethodInfo writeStringLineMethod = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) });
                ilGenerator.Emit(OpCodes.Ldstr,"New York");
                ilGenerator.Emit(OpCodes.Stsfld, areaFieldBuilder);
    
                ilGenerator.Emit(OpCodes.Ldsfld, areaFieldBuilder);
                ilGenerator.Emit(OpCodes.Call, writeStringLineMethod);
    
                ilGenerator.Emit(OpCodes.Ldarg_0);//生成this
                ilGenerator.Emit(OpCodes.Ldstr, "Tom");
                ilGenerator.Emit(OpCodes.Stfld, nameFieldBuilder);
    
                ilGenerator.Emit(OpCodes.Ldarg_0);//生成this
                ilGenerator.Emit(OpCodes.Ldfld, areaFieldBuilder);
                ilGenerator.Emit(OpCodes.Call, writeStringLineMethod);
    
                ilGenerator.Emit(OpCodes.Ret);
    
            }
    
            public static void Generate()
            {
                InitAssembly();
    
                typeBuilder = moduleBuilder.DefineType(namespaceName + "." + typeName, TypeAttributes.Public);
                Emit_IL();
    
                SaveAssembly();
                Console.WriteLine("生成成功");
            }
    
    
            static void InitAssembly()
            {
                AssemblyName assemblyName = new AssemblyName(namespaceName);
                assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
                moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name, binaryName);
            }
    
            static void SaveAssembly()
            {
                Type t = typeBuilder.CreateType(); //完成Type,这是必须的
                assemblyBuilder.Save(binaryName);
            }
        }
    }
    View Code
  • 相关阅读:
    Kafka如何保证读写的跨分区与会话
    Kafka topic中的partition的leader选举
    Kafka为什么这么快
    sqoop导入导出
    为什么要用redis去重
    bypass SortShuffleManager的bypass运行机制
    大数据常用端口号
    vector基础
    【拓扑排序】
    【POJ】Crazy Search(hash)
  • 原文地址:https://www.cnblogs.com/tkt2016/p/8624256.html
Copyright © 2020-2023  润新知