// 安装 System.Reflection.Emit
// 工具:ILSpy
using System;
using System.Reflection;
using System.Reflection.Emit;
// 首先申明程序集名称
AssemblyName assemblyName = new AssemblyName("MyAssembly");
// 获取程序集构造器
AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
// 通过程序集获取模块构造器
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MyModule");
// 通过模块获取类型构造器
// public class MyType { }
TypeBuilder typeBuilder = moduleBuilder.DefineType("MyType", TypeAttributes.Public);
//typeBuilder.DefineTypeInitializer(); // 静态构造函数
#region 动态生成静态方法
/*
* public static void MyMethodForSayHello()
* {
* Console.WriteLine("Hello, jieke");
* Console.ReadLine();
* }
*/
{
// 通过类型获取方法构造器
MethodBuilder methodBuilder = typeBuilder.DefineMethod("MyMethodForSayHello", MethodAttributes.Public | MethodAttributes.Static, null, null);
// 通过方法获取IL生成器
ILGenerator ilGenerator = methodBuilder.GetILGenerator();
// 通过IL定义方法体
ilGenerator.Emit(OpCodes.Ldstr, "Hello, jieke"); // 载入字符串
ilGenerator.Emit(OpCodes.Call, typeof(Console).GetMethod(nameof(Console.WriteLine), new Type[] { typeof(string) })); // 输出字符串到控制台
ilGenerator.Emit(OpCodes.Call, typeof(Console).GetMethod(nameof(Console.ReadLine))); // 从控制台读取一行输入
ilGenerator.Emit(OpCodes.Pop); // 将读取到的数据从栈顶弹出
ilGenerator.Emit(OpCodes.Ret); // 函数返回
}
#endregion
#region 生成带参数和返回值得的实例方法
/*
* public int Add(int x, int y)
* {
* return x + y;
* }
*/
{
Type returnType = typeof(int);
Type[] parameterTypes = new Type[] { typeof(int), typeof(int) };
// 通过类型获取方法构造器
MethodBuilder methodBuilder = typeBuilder.DefineMethod("Add", MethodAttributes.Public | MethodAttributes.HideBySig, returnType, parameterTypes); // 定义函数申明
methodBuilder.DefineParameter(1, ParameterAttributes.None, "x"); // 定义第一个参数
methodBuilder.DefineParameter(2, ParameterAttributes.None, "y"); // 定义第二个参数
// 通过方法获取IL生成器
ILGenerator ilGenerator = methodBuilder.GetILGenerator();
// 定义本地变量
LocalBuilder local1 = ilGenerator.DeclareLocal(typeof(int));
ilGenerator.Emit(OpCodes.Nop);
// 通过IL定义方法体
ilGenerator.Emit(OpCodes.Ldarg_1); // 载入索引为1的参数
ilGenerator.Emit(OpCodes.Ldarg_2); // 载入索引为2的参数
ilGenerator.Emit(OpCodes.Add); // 执行两数相加
ilGenerator.Emit(OpCodes.Stloc_0); // 将栈顶的数据弹出放到本地变量列表索引为零的变量上
ilGenerator.Emit(OpCodes.Ldloc_0); // 将本地变量列表索引为零的变量上的值放到计算堆栈上
ilGenerator.Emit(OpCodes.Ret); // 函数返回
}
#endregion
#region 定义字段
FieldBuilder fieldName;
FieldBuilder fieldAge;
{
// private string _name = string.Empty;
fieldName = typeBuilder.DefineField("_name", typeof(string), FieldAttributes.Private);
//fieldName.SetConstant(string.Empty);
// private string _age = 18;
fieldAge = typeBuilder.DefineField("_age", typeof(int), FieldAttributes.Private);
//fieldAge.SetConstant(18);
}
#endregion
#region 定义属性
{
// public string Name { get { return this._name; } set { this._name = value; } }
{
MethodBuilder methodGetName = typeBuilder.DefineMethod("GetName", MethodAttributes.Public, typeof(string), null);
MethodBuilder methodSetName = typeBuilder.DefineMethod("SetName", MethodAttributes.Public, null, new Type[] { typeof(string) });
ILGenerator iLGeneratorForGetName = methodGetName.GetILGenerator();
iLGeneratorForGetName.Emit(OpCodes.Ldarg_0); // 载入当前实例,this
iLGeneratorForGetName.Emit(OpCodes.Ldfld, fieldName); // 载入字段
iLGeneratorForGetName.Emit(OpCodes.Ret); // 返回
ILGenerator iLGeneratorForSetName = methodSetName.GetILGenerator();
iLGeneratorForSetName.Emit(OpCodes.Ldarg_0); // 载入当前实例,this
iLGeneratorForSetName.Emit(OpCodes.Ldarg_1); // 载入第一个参数
iLGeneratorForSetName.Emit(OpCodes.Stfld, fieldName); // 将栈顶的数据设置到字段上
iLGeneratorForSetName.Emit(OpCodes.Ret); // 返回
PropertyBuilder propertyName = typeBuilder.DefineProperty("Name", PropertyAttributes.None, CallingConventions.HasThis, typeof(string), null);
propertyName.SetGetMethod(methodGetName);
propertyName.SetSetMethod(methodSetName);
}
// public int Age { get { return this._age; } set { this._age = value; } }
{
MethodBuilder methodGetAge = typeBuilder.DefineMethod("GetAge", MethodAttributes.Public, typeof(int), null);
MethodBuilder methodSetAge = typeBuilder.DefineMethod("SetAge", MethodAttributes.Public, null, new Type[] { typeof(int) });
ILGenerator iLGeneratorForGetAge = methodGetAge.GetILGenerator();
iLGeneratorForGetAge.Emit(OpCodes.Ldarg_0); // 载入当前实例,this
iLGeneratorForGetAge.Emit(OpCodes.Ldfld, fieldAge); // 载入字段
iLGeneratorForGetAge.Emit(OpCodes.Ret); // 返回
ILGenerator iLGeneratorForSetAge = methodSetAge.GetILGenerator();
iLGeneratorForSetAge.Emit(OpCodes.Ldarg_0); // 载入当前实例,this
iLGeneratorForSetAge.Emit(OpCodes.Ldarg_1); // 载入第一个参数
iLGeneratorForSetAge.Emit(OpCodes.Stfld, fieldAge); // 将栈顶的数据设置到字段上
iLGeneratorForSetAge.Emit(OpCodes.Ret); // 返回
PropertyBuilder propertyAge = typeBuilder.DefineProperty("Age", PropertyAttributes.None, CallingConventions.HasThis, typeof(int), null);
propertyAge.SetGetMethod(methodGetAge);
propertyAge.SetSetMethod(methodSetAge);
}
}
#endregion
#region 定义构造函数
{
/*
public MyType(string name, int age) { this._name = name; this._age = age; }
*/
{
Type objectType = Type.GetType("System.Object");
ConstructorInfo objectCtor = objectType.GetConstructor(Array.Empty<Type>());
Type[] constructorArgs = { typeof(string), typeof(int) };
ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, constructorArgs);
ILGenerator iLGeneratorForConstructor = constructorBuilder.GetILGenerator();
iLGeneratorForConstructor.Emit(OpCodes.Ldarg_0); // 载入当前对象
iLGeneratorForConstructor.Emit(OpCodes.Call, objectCtor); // 调用父类构造函数
iLGeneratorForConstructor.Emit(OpCodes.Ldarg_0); // 载入当前对象
iLGeneratorForConstructor.Emit(OpCodes.Ldarg_1); // 载入第一个参数
iLGeneratorForConstructor.Emit(OpCodes.Stfld, fieldName); // 将第一个参数的值设置到_name field上
iLGeneratorForConstructor.Emit(OpCodes.Ldarg_0); // 载入当前对象
iLGeneratorForConstructor.Emit(OpCodes.Ldarg_2); // 载入第二个参数
iLGeneratorForConstructor.Emit(OpCodes.Stfld, fieldAge); // 将第二个参数的值设置到_age field上
iLGeneratorForConstructor.Emit(OpCodes.Ret);
}
/*
public MyType() { }
*/
{
Type objectType = Type.GetType("System.Object");
ConstructorInfo objectCtor = objectType.GetConstructor(Array.Empty<Type>());
ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, null);
ILGenerator iLGeneratorForConstructor = constructorBuilder.GetILGenerator();
iLGeneratorForConstructor.Emit(OpCodes.Ldarg_0); // 载入当前对象
iLGeneratorForConstructor.Emit(OpCodes.Call, objectCtor); // 调用父类构造函数
iLGeneratorForConstructor.Emit(OpCodes.Ret);
}
}
#endregion
#region 覆写父类的ToString方法
{
MethodBuilder methodToString = typeBuilder.DefineMethod("ToString", MethodAttributes.Virtual | MethodAttributes.Public, typeof(string), null);
ILGenerator iLGenerator = methodToString.GetILGenerator();
var local = iLGenerator.DeclareLocal(typeof(string)); // 创建本地变量
iLGenerator.Emit(OpCodes.Ldstr, "Name: [{0}], Age: [{1}]"); // 载入字符串模版
iLGenerator.Emit(OpCodes.Ldarg_0); // 载入当前对象,this
iLGenerator.Emit(OpCodes.Ldfld, fieldName); // 载入_name field
iLGenerator.Emit(OpCodes.Ldarg_0); // 载入当前对象,this
iLGenerator.Emit(OpCodes.Ldfld, fieldAge); // 载入_age field
iLGenerator.Emit(OpCodes.Box, typeof(int)); // 将值类型装箱为object
iLGenerator.Emit(OpCodes.Call, typeof(string).GetMethod(nameof(string.Format), new Type[] { typeof(string), typeof(object), typeof(object) }));
iLGenerator.Emit(OpCodes.Stloc, local); // 弹出栈顶的值并存储到变量中
iLGenerator.Emit(OpCodes.Ldloc, local); // 将变量的值载入到栈顶
iLGenerator.Emit(OpCodes.Ret); // 函数返回
}
#endregion
//typeBuilder.DefineInitializedData("_name", Encoding.Unicode.GetBytes("empty"), FieldAttributes.Private);
//typeBuilder.DefineInitializedData("_age", BitConverter.GetBytes(18), FieldAttributes.Private);
// 生成类型
Type myType = typeBuilder.CreateType();
// 使用动态生成的类型
#region 使用静态方法
{
dynamic staticInstance = new StaticMembersDynamicWrapper(myType);
staticInstance.MyMethodForSayHello();
}
#endregion
#region 使用实例方法
{
dynamic instance = Activator.CreateInstance(myType);
dynamic result = instance.Add(1, 1);
instance.Age = 10;
Console.WriteLine(instance);
instance.Name = "jieke";
Console.WriteLine(instance.Name);
}
#endregion
#region 使用有参构造函数、属性及ToString方法
{
dynamic instance = Activator.CreateInstance(myType, "jieke", 20);
Console.WriteLine(instance);
instance.Age++;
instance.Age = instance.Age + 1;
PropertyInfo ageProperty = myType.GetProperty("Age");
int age = ageProperty.GetValue(instance);
age++;
ageProperty.SetValue(instance, age);
Console.WriteLine(instance);
}
#endregion
// 秒懂C#通过Emit动态生成代码 https://www.cnblogs.com/gaochundong/archive/2013/06/01/csharp_emit_generate_assembly.html
// C#使用Emit生成构造函数和属性 https://www.cnblogs.com/gaochundong/archive/2013/06/01/csharp_emit_create_constructor_properties.html
// C#使用Emit构造拦截器动态代理类 https://www.cnblogs.com/gaochundong/archive/2013/06/01/csharp_emit_create_interceptor_proxy.html
// c# dynamic 类型调用静态方法实例 https://blog.csdn.net/weixin_34332905/article/details/90153259
// 说说emit(中)ILGenerator https://www.cnblogs.com/xuanhun/archive/2012/06/22/2558698.html
// IL指令集 https://wenku.baidu.com/view/143ab58a6529647d27285234.html
// Emit学习(2) - IL - 值类型和引用类型(补) https://www.cnblogs.com/elvinle/p/6015097.html
// Emit学习(3) - OpCodes - 动态添加属性、构造函数、方法 https://www.cnblogs.com/elvinle/p/6007536.html
网友评论