首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从MethodInfo生成DynamicMethod

从MethodInfo生成DynamicMethod
EN

Stack Overflow用户
提问于 2010-06-24 02:24:24
回答 2查看 2.9K关注 0票数 3

我正在阅读Joel Pobar的一篇关于反射的Dodge Common Performance Pitfalls to Craft Speedy Applications文章,我正在查看一段无法编译的特定代码(稍微修改一下,以缩小到特定错误的范围,因为他的示例有更多错误):

代码语言:javascript
复制
MethodInfo writeLine = typeof(Console).GetMethod("WriteLine");
RuntimeMethodHandle myMethodHandle = writeLine.MethodHandle;
DynamicMethod dm = new DynamicMethod(
    "HelloWorld",          // name of the method
    typeof(void),          // return type of the method
    new Type[]{},          // argument types for the method
    false);                // skip JIT visibility checks

ILGenerator il = dm.GetILGenerator();
il.Emit(OpCodes.Ldstr, "Hello, world");
il.Emit(OpCodes.Call, myMethodHandle); // <-- 2 errors here
il.Emit(OpCodes.Ret);

错误是:

代码语言:javascript
复制
Program.cs(350,13): error CS1502: The best overloaded method match for 'System.Reflection.Emit.ILGenerator.Emit(System.Reflection.Emit.OpCode, byte)' has some invalid arguments
Program.cs(350,35): error CS1503: Argument '2': cannot convert from 'System.RuntimeMethodHandle' to 'byte'

ILGenerator可以使用MethodInfo进行Emit,但它似乎不支持MethodHandle...有谁知道如何让这个样本正常工作吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-06-24 03:20:36

像这样吗?

代码语言:javascript
复制
        MethodInfo writeLine = typeof(Console).GetMethod("WriteLine", new Type[] {typeof(string)});
        RuntimeMethodHandle myMethodHandle = writeLine.MethodHandle;
        DynamicMethod dm = new DynamicMethod(
            "HelloWorld",          // name of the method
            typeof(void),          // return type of the method
            new Type[] { },          // argument types for the method
            false);                // skip JIT visibility checks

        ILGenerator il = dm.GetILGenerator();
        il.Emit(OpCodes.Ldstr, "Hello, world");
        il.EmitCall(OpCodes.Call, writeLine, null);
        il.Emit(OpCodes.Ret);
        // test it 
        Action act = (Action)dm.CreateDelegate(typeof(Action));
        act();

更改:

  • 我使用了一个调整过的GetMethod来查找(string)重载(否则它是一个模棱两可的匹配)
  • 使用MethodInfo,而不是句柄(因为这是ILGenerator想要的)
  • 使用EmitCall (另一个可能也能用,但我知道这样也能用)
票数 3
EN

Stack Overflow用户

发布于 2014-03-04 18:37:08

通过Nuget.org上的这个库:ClassWrapper

它为内部使用动态生成的方法的类型创建包装器。所以没有使用反射(只在ClassWrapperDescriptor.Load方法中生成动态表达式)

给定的,例如名为SampleClass的e类

代码语言:javascript
复制
//Create the class wrapper descriptor, this can be cached and reused!
var classWrapperDescriptor = new ClassWrapperDescriptor(typeof(SampleClass));
//Initialize the descriptor
classWrapperDescriptor.Load();

//Create the instance of our object
object instance = new SampleClass();

//Create an instance of the wrapper
var classWrapper = classWrapperDescriptor.CreateWrapper(instance);

//Set a property
classWrapper.Set("StringProperty","test");

//Get a property
var stringPropertyValue = classWrapper.Get<string>("StringProperty");

//Invoke a method without return statement
classWrapper.Invoke("ParamMethod", "paramValue");

//Invoke a method witho return statement
var result = classWrapper.Invoke<int>("ReturnMethod", "paramValue");

任何关于这个库的反馈都是非常感谢的!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3104404

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档