下載app免費領取會員
相關類如下,目標是用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);
}
}
實現(xiàn)如下:
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;
}
}
本文版權歸腿腿教學網(wǎng)及原創(chuàng)作者所有,未經(jīng)授權,謝絕轉載。
上一篇:二次開發(fā)教程:Emit DynamicMethod