完善主体资料,免费赠送VIP会员!
* 主体类型
* 企业名称
* 信用代码
* 所在行业
* 企业规模
* 所在职位
* 姓名
* 所在行业
* 学历
* 工作性质
请先选择行业
您还可以选择以下福利:
行业福利,领完即止!

下载app免费领取会员

NULL

5cdd2dc095060.jpg

二次开发教程:Hello Emit

发布于:2019-07-24 16:37:06

网友投稿

更多

相关类如下,目标是用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;

}

}

本文版权归腿腿教学网及原创作者所有,未经授权,谢绝转载。

未标题-1.jpg

上一篇:二次开发教程:Emit DynamicMethod

下一篇:二次开发教程:研究下WPF 数据binding 原理

60acb4e0ef112.png