C # - 5395
Consente di emettere codice cil per l'aggiunta utilizzando un metodo dinamico. In realtà io emetto codice, che a sua volta emette codice per chiamare l'aggiunta di numeri interi. La Add()
seguente funzione crea un metodo dinamico che, quando eseguito, crea un metodo dinamico per chiamare l'aggiunta di numeri interi.
using System;
using System.Reflection.Emit;
namespace JA
{
class Program
{
static void Main(string[] args)
{
int z=Add(1, 2);
// z = 3
}
// Emit MSIL to emit MSIL
public static int Add(int x, int y)
{
Type delegate_type=typeof(Func<int, int, int>);
DynamicMethod method=new DynamicMethod(typeof(int).ToString()+".op_Addition",
typeof(int),
new Type[] { typeof(int), typeof(int) }, typeof(Program));
ILGenerator generator=method.GetILGenerator();
LocalBuilder method1=generator.DeclareLocal(typeof(DynamicMethod));
LocalBuilder generator1=generator.DeclareLocal(typeof(ILGenerator));
LocalBuilder add1=generator.DeclareLocal(typeof(Func<int, int, int>));
LocalBuilder args1=generator.DeclareLocal(typeof(Type[]));
generator.Emit(OpCodes.Ldtoken, typeof(int));
generator.Emit(OpCodes.Call,
typeof(Type).GetMethod("GetTypeFromHandle",
System.Reflection.BindingFlags.Public|
System.Reflection.BindingFlags.Static));
generator.Emit(OpCodes.Callvirt,
typeof(object).GetMethod("ToString",
System.Reflection.BindingFlags.Public|
System.Reflection.BindingFlags.Instance));
generator.Emit(OpCodes.Ldstr, ".op_Addition");
generator.Emit(OpCodes.Call,
typeof(string).GetMethod("Concat",
new Type[] { typeof(string), typeof(string) }));
generator.Emit(OpCodes.Ldtoken, typeof(int));
generator.Emit(OpCodes.Call,
typeof(Type).GetMethod("GetTypeFromHandle",
System.Reflection.BindingFlags.Public|
System.Reflection.BindingFlags.Static));
generator.Emit(OpCodes.Ldc_I4, 2);
generator.Emit(OpCodes.Newarr, typeof(Type));
generator.Emit(OpCodes.Stloc_3);
generator.Emit(OpCodes.Ldloc_3);
generator.Emit(OpCodes.Ldc_I4, 0);
generator.Emit(OpCodes.Ldtoken, typeof(int));
generator.Emit(OpCodes.Call,
typeof(Type).GetMethod("GetTypeFromHandle",
System.Reflection.BindingFlags.Public|
System.Reflection.BindingFlags.Static));
generator.Emit(OpCodes.Stelem_Ref);
generator.Emit(OpCodes.Ldloc_3);
generator.Emit(OpCodes.Ldc_I4, 1);
generator.Emit(OpCodes.Ldtoken, typeof(int));
generator.Emit(OpCodes.Call,
typeof(Type).GetMethod("GetTypeFromHandle",
System.Reflection.BindingFlags.Public|
System.Reflection.BindingFlags.Static));
generator.Emit(OpCodes.Stelem_Ref);
generator.Emit(OpCodes.Ldloc_3);
generator.Emit(OpCodes.Ldtoken, typeof(Program));
generator.Emit(OpCodes.Call,
typeof(Type).GetMethod("GetTypeFromHandle",
System.Reflection.BindingFlags.Public|
System.Reflection.BindingFlags.Static));
generator.Emit(OpCodes.Newobj,
typeof(DynamicMethod).GetConstructor(
new Type[] { typeof(string), typeof(Type), typeof(Type[]), typeof(Type) }));
generator.Emit(OpCodes.Stloc_0);
generator.Emit(OpCodes.Ldloc_0);
generator.Emit(OpCodes.Callvirt,
typeof(DynamicMethod).GetMethod("GetILGenerator",
Type.EmptyTypes));
generator.Emit(OpCodes.Stloc_1);
generator.Emit(OpCodes.Ldloc_1);
generator.Emit(OpCodes.Ldtoken, typeof(int));
generator.Emit(OpCodes.Call,
typeof(Type).GetMethod("GetTypeFromHandle",
System.Reflection.BindingFlags.Public|
System.Reflection.BindingFlags.Static));
generator.Emit(OpCodes.Callvirt,
typeof(ILGenerator).GetMethod("DeclareLocal",
new Type[] { typeof(Type) }));
generator.Emit(OpCodes.Pop);
generator.Emit(OpCodes.Ldloc_1);
generator.Emit(OpCodes.Ldsfld,
typeof(OpCodes).GetField("Ldarg_0",
System.Reflection.BindingFlags.Public|System.Reflection.BindingFlags.Static));
generator.Emit(OpCodes.Callvirt,
typeof(ILGenerator).GetMethod("Emit", new Type[] { typeof(OpCode) }));
generator.Emit(OpCodes.Ldloc_1);
generator.Emit(OpCodes.Ldsfld,
typeof(OpCodes).GetField("Ldarg_1",
System.Reflection.BindingFlags.Public|System.Reflection.BindingFlags.Static));
generator.Emit(OpCodes.Callvirt,
typeof(ILGenerator).GetMethod("Emit", new Type[] { typeof(OpCode) }));
generator.Emit(OpCodes.Ldloc_1);
generator.Emit(OpCodes.Ldsfld,
typeof(OpCodes).GetField("Add",
System.Reflection.BindingFlags.Public|System.Reflection.BindingFlags.Static));
generator.Emit(OpCodes.Callvirt,
typeof(ILGenerator).GetMethod("Emit", new Type[] { typeof(OpCode) }));
generator.Emit(OpCodes.Ldloc_1);
generator.Emit(OpCodes.Ldsfld,
typeof(OpCodes).GetField("Stloc_0",
System.Reflection.BindingFlags.Public|System.Reflection.BindingFlags.Static));
generator.Emit(OpCodes.Callvirt,
typeof(ILGenerator).GetMethod("Emit", new Type[] { typeof(OpCode) }));
generator.Emit(OpCodes.Ldloc_1);
generator.Emit(OpCodes.Ldsfld,
typeof(OpCodes).GetField("Ldloc_0",
System.Reflection.BindingFlags.Public|System.Reflection.BindingFlags.Static));
generator.Emit(OpCodes.Callvirt,
typeof(ILGenerator).GetMethod("Emit", new Type[] { typeof(OpCode) }));
generator.Emit(OpCodes.Ldloc_1);
generator.Emit(OpCodes.Ldsfld,
typeof(OpCodes).GetField("Ret",
System.Reflection.BindingFlags.Public|System.Reflection.BindingFlags.Static));
generator.Emit(OpCodes.Callvirt,
typeof(ILGenerator).GetMethod("Emit", new Type[] { typeof(OpCode) }));
generator.Emit(OpCodes.Ldloc_0);
generator.Emit(OpCodes.Ldtoken, typeof(Func<int, int, int>));
generator.Emit(OpCodes.Call,
typeof(Type).GetMethod("GetTypeFromHandle",
System.Reflection.BindingFlags.Public|
System.Reflection.BindingFlags.Static));
generator.Emit(OpCodes.Callvirt,
typeof(DynamicMethod).GetMethod("CreateDelegate",
new Type[] { typeof(Type) }));
generator.Emit(OpCodes.Isinst, typeof(Func<int, int, int>));
generator.Emit(OpCodes.Stloc_2);
generator.Emit(OpCodes.Ldloc_2);
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Ldarg_1);
generator.Emit(OpCodes.Callvirt,
typeof(Func<int, int, int>).GetMethod("Invoke",
System.Reflection.BindingFlags.Public|System.Reflection.BindingFlags.Instance));
generator.Emit(OpCodes.Ret);
Func<int, int, int> add2=method.CreateDelegate(typeof(Func<int, int, int>)) as Func<int, int, int>;
return add2(x, y);
}
}
}