Hello Emit

相关类如下,目标是用Emit生成一个Writer类,并返回一个IWriter接口,使用接口调用

	public interface IWriter
	{
		void Write(string msg, string msg1);
	}

	public class Writer: IWriter
	{
		public  void Write(string msg,string msg1)
		{
			string ex = "ex";
			string str = msg + msg1 + ex;
			Console.WriteLine(str);
		}
	}

实现如下:

	class Program
	{
		static void Main(string[] args)
		{
			IWriter writer = GetWriter();
			writer.Write("test1", "test2");
			Console.ReadLine();
		}

		private static IWriter GetWriter()
		{
			var assemblyName = new AssemblyName("DynamicAssembly");

			var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName,
				AssemblyBuilderAccess.RunAndCollect);
			var moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name);


			var typeBuilder = moduleBuilder.DefineType("DefaultType", TypeAttributes.Public| TypeAttributes.Class);

			typeBuilder.AddInterfaceImplementation(typeof(IWriter));

			Type strType = typeof(string);

			var methodBuilder = typeBuilder.DefineMethod("Write", MethodAttributes.Public| MethodAttributes.Virtual,typeof(void),new Type[]{ strType , strType });

			methodBuilder.DefineParameter(1, ParameterAttributes.In, "msg");//Ldarg_1

			methodBuilder.DefineParameter(2, ParameterAttributes.In, "msg1");//Ldarg_1

			var iLGenerator = methodBuilder.GetILGenerator();

			iLGenerator.DeclareLocal(typeof(string));//Ldloc_0
			iLGenerator.DeclareLocal(typeof(string));//Ldloc_1

			///https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.ldarg_1?view=netframework-4.7.2

			iLGenerator.Emit(OpCodes.Nop);
			iLGenerator.Emit(OpCodes.Ldstr,"ex");//Pushes a new object reference to a string literal stored in the metadata.
			iLGenerator.Emit(OpCodes.Stloc_0); // Pops the current value from the top of the evaluation stack and stores it in a the local variable list at index 0.
											   // 上一句是将ex 放到栈里(?),这句从栈里取出来赋值给 Ldloc_0
			iLGenerator.Emit(OpCodes.Ldarg_1);
			iLGenerator.Emit(OpCodes.Ldarg_2);
			iLGenerator.Emit(OpCodes.Ldloc_0);
			iLGenerator.Emit(OpCodes.Call, GetStringConcat());//计算结果保存在了栈里(?)

			iLGenerator.Emit(OpCodes.Stloc_1);//将计算结果取出来赋值给 Ldloc_1
			iLGenerator.Emit(OpCodes.Ldloc_1);//将 Ldloc_1 放入栈

			iLGenerator.Emit(OpCodes.Call, GetWriteLine());

			iLGenerator.Emit(OpCodes.Nop);
			iLGenerator.Emit(OpCodes.Ret);

			var type = typeBuilder.CreateType();

			return (IWriter)Activator.CreateInstance(type);
		}

		private static MethodInfo GetStringConcat()
		{
			Type type = typeof(string);
			MethodInfo method =type.GetMethod("Concat", new Type[] {type, type, type});
			return method;
		}
		private static MethodInfo GetWriteLine()
		{
			Type type = typeof(Console);
			MethodInfo method = type.GetMethod("WriteLine", new Type[] {typeof(string) });
			return method;
		}
	}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值