下载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);
}
}
实现如下:
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;
}
}
本文版权归腿腿教学网及原创作者所有,未经授权,谢绝转载。