c# 使用反射Reflection的Emit实现动态创建元数据及可执行文件

 1 void Main()
 2 {
 3     string projectName = "HelloWorld";
 4 
 5     AssemblyName assemblyName = new AssemblyName()
 6     {
 7        Name = projectName    
 8     };
 9     
10     //生成一个动态程序集
11     AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Save);
12     
13     //生成程序集模块
14     ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(projectName, projectName + ".exe",true);
15     
16     //设置类
17     TypeBuilder typeBuilder = moduleBuilder.DefineType("Program", TypeAttributes.Class);
18     //设置方法    
19     MethodBuilder mainMethodBuilder = typeBuilder.DefineMethod("Main", MethodAttributes.Public |  MethodAttributes.Static, typeof(void),Type.EmptyTypes);
20     
21     //指定IL
22     ILGenerator ilMain = mainMethodBuilder.GetILGenerator();
23     //声明string类型变量
24     LocalBuilder msgLocal = ilMain.DeclareLocal(typeof(string));
25     //定义变量名
26     msgLocal.SetLocalSymInfo("letter");
27     ilMain.Emit(OpCodes.Ldstr,"hello world");
28     ilMain.Emit(OpCodes.Stloc,msgLocal);
29     ilMain.Emit(OpCodes.Ldloc, msgLocal);
30     ilMain.EmitCall(OpCodes.Call, Type.GetType("System.Console").GetMethod("WriteLine", new Type[] {typeof(string)}),null);
31     ilMain.Emit(OpCodes.Ret);
32     
33     typeBuilder.CreateType();
34     
35     assemblyBuilder.SetEntryPoint(mainMethodBuilder);
36     assemblyBuilder.Save(projectName + ".exe");
37     
38     
39 }
40 
41 // Define other methods and classes here

 

 

另一示例:

 

 1 // define assembly and module
 2 var propertyName = "Name";
 3 var propertyType = typeof(string);
 4 var ab = AssemblyBuilder.DefineDynamicAssembly(
 5              new AssemblyName("dynamicAssembly"), 
 6              AssemblyBuilderAccess.Save);
 7 var mb = ab.DefineDynamicModule("dynamicModule", "dynamicModule.dll");
 8 
 9 // define type, field and property
10 var tb = mb.DefineType("dynamicType");
11 var fb = tb.DefineField("_name", propertyType, FieldAttributes.Private);
12 var pb = tb.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, Type.EmptyTypes);
13 var get = tb.DefineMethod("get_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, propertyType, Type.EmptyTypes);
14 var set = tb.DefineMethod("set_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, null, new[] { propertyType });
15 
16 // write the IL for the get method
17 var getIl = get.GetILGenerator();
18 getIl.Emit(OpCodes.Ldarg_0); // this
19 getIl.Emit(OpCodes.Ldfld, fb); // _name field
20 getIl.Emit(OpCodes.Ret);
21 
22 // write the IL for the set method
23 var setIl = set.GetILGenerator();
24 Label exitSet = setIl.DefineLabel(); // define label to jump in case condition is false
25 setIl.Emit(OpCodes.Ldarg_0); // this
26 setIl.Emit(OpCodes.Ldfld, fb); // _name field
27 setIl.Emit(OpCodes.Ldarg_1); // value
28 var inequality = propertyType.GetMethod("op_Inequality", new[] { propertyType, propertyType });
29 setIl.Emit(OpCodes.Call, inequality); // '!=' method
30 setIl.Emit(OpCodes.Brfalse_S, exitSet); // check for inequality
31 setIl.Emit(OpCodes.Ldstr, "changedto:"); // load string literal
32 setIl.Emit(OpCodes.Ldarg_1); // value
33 var concat = propertyType.GetMethod("Concat", new[] { propertyType, propertyType });
34 setIl.Emit(OpCodes.Call, concat); // concat two strings (literal + value)
35 var writeline = typeof(Console).GetMethod("WriteLine", new[] { propertyType });
36 setIl.Emit(OpCodes.Call, writeline); // write
37 setIl.Emit(OpCodes.Ldarg_0); // this
38 setIl.Emit(OpCodes.Ldarg_1); // value
39 setIl.Emit(OpCodes.Stfld, fb); // save the new value into _name
40 setIl.MarkLabel(exitSet); // mark the label
41 setIl.Emit(OpCodes.Ret); // return
42 pb.SetGetMethod(get);
43 pb.SetSetMethod(set);
44 
45 tb.CreateType(); // complete the type
46 ab.Save("dynamicModule.dll"); // save the assembly to disk

 

结果代码

 1 internal class dynamicType
 2 {
 3     private string _name;
 4 
 5     public string Name
 6     {
 7         get
 8         {
 9             return this._name;
10         }
11         set
12         {
13             if (this._name != value)
14             {
15                  Console.WriteLine("changedto:" + value);
16                  this._name = value;
17             }
18         }
19     }
20 }

 

posted @ 2021-02-05 11:23  TonysDad  阅读(233)  评论(0编辑  收藏  举报