在 .Net 中用 Emit 动态创建方法很容易,
可我想获取一个方法体的字节码,应该怎么做?
解决方案 »
- 关于DataTable.Select(条件) not like 的问题
- Winform中debug输出在哪里可以看到?
- 网站UI设计人员请进!
- 你們做數據庫方面開發時,有沒有把每個數據記錄做成一個類???還是直接用 DataSet ?
- 想请教一个关于c#编写directx的问题
- 使用Adapter.Update(DataSet)的问题,大大帮我看看代码,100分相送!!!
- 高分求教NumericUpDown问题
- 问一个关于vb 6.0到vc#的一个字符串声明(在线等.急.)
- 会 c# 截取字符串 请来!!!
- 求助:如何触发或实现windowform的datagrid邦定的checkbox或textbox的事件或方法?
- 自定义类组成数组的疑惑?
- 如何获得方法体的字节码?用 MethodHandle ?
就是 ILGenerator 的逆向操作,
ILGenerator 是将字节码写入方法体,
如何从方法体中读取这些字节码呢?
3tzjq 兄, 我没骗人啊,
如果能帮我解决这个问题,
2000 分拱手奉上,绝对一分不少。
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;class DynamicJumpTableDemo{ public static Type BuildMyType()
{
AppDomain myDomain = Thread.GetDomain();
AssemblyName myAsmName = new AssemblyName();
myAsmName.Name = "MyDynamicAssembly"; AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(
myAsmName,
AssemblyBuilderAccess.Run);
ModuleBuilder myModBuilder = myAsmBuilder.DefineDynamicModule(
"MyJumpTableDemo"); TypeBuilder myTypeBuilder = myModBuilder.DefineType("JumpTableDemo",
TypeAttributes.Public);
MethodBuilder myMthdBuilder = myTypeBuilder.DefineMethod("SwitchMe",
MethodAttributes.Public |
MethodAttributes.Static,
typeof(string),
new Type[] {typeof(int)}); ILGenerator myIL = myMthdBuilder.GetILGenerator(); Label defaultCase = myIL.DefineLabel();
Label endOfMethod = myIL.DefineLabel(); // We are initializing our jump table. Note that the labels
// will be placed later using the MarkLabel method. Label[] jumpTable = new Label[] { myIL.DefineLabel(),
myIL.DefineLabel(),
myIL.DefineLabel(),
myIL.DefineLabel(),
myIL.DefineLabel() }; // arg0, the number we passed, is pushed onto the stack.
// In this case, due to the design of the code sample,
// the value pushed onto the stack happens to match the
// index of the label (in IL terms, the index of the offset
// in the jump table). If this is not the case, such as
// when switching based on non-integer values, rules for the correspondence
// between the possible case values and each index of the offsets
// must be established outside of the ILGenerator.Emit calls,
// much as a compiler would. myIL.Emit(OpCodes.Ldarg_0);
myIL.Emit(OpCodes.Switch, jumpTable);
// Branch on default case
myIL.Emit(OpCodes.Br_S, defaultCase); // Case arg0 = 0
myIL.MarkLabel(jumpTable[0]);
myIL.Emit(OpCodes.Ldstr, "are no bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod); // Case arg0 = 1
myIL.MarkLabel(jumpTable[1]);
myIL.Emit(OpCodes.Ldstr, "is one banana");
myIL.Emit(OpCodes.Br_S, endOfMethod); // Case arg0 = 2
myIL.MarkLabel(jumpTable[2]);
myIL.Emit(OpCodes.Ldstr, "are two bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod); // Case arg0 = 3
myIL.MarkLabel(jumpTable[3]);
myIL.Emit(OpCodes.Ldstr, "are three bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod); // Case arg0 = 4
myIL.MarkLabel(jumpTable[4]);
myIL.Emit(OpCodes.Ldstr, "are four bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod); // Default case
myIL.MarkLabel(defaultCase);
myIL.Emit(OpCodes.Ldstr, "are many bananas"); myIL.MarkLabel(endOfMethod);
myIL.Emit(OpCodes.Ret);
return myTypeBuilder.CreateType(); } public static void Main()
{
Type myType = BuildMyType();
Console.Write("Enter an integer between 0 and 5: ");
int theValue = Convert.ToInt32(Console.ReadLine()); Console.WriteLine("---");
Object myInstance = Activator.CreateInstance(myType, new object[0]);
Console.WriteLine("Yes, there {0} today!", myType.InvokeMember("SwitchMe",
BindingFlags.InvokeMethod,
null,
myInstance,
new object[] {theValue}));
}}
evaELLIS 兄,我知道如何用 Emit 动态创建方法,
可我希望得到的是方法创建后的字节码。