C # - 5395
Cho phép phát mã cil để thêm vào bằng phương thức động. Thật ra tôi phát mã, đến lượt nó phát ra mã để gọi phép cộng số nguyên. Hàm Add()
bên dưới xây dựng một phương thức động, khi chạy sẽ xây dựng một phương thức động để gọi phép cộng số nguyên.
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);
}
}
}