c# - 如何将通过反射获得的方法分配给委托(delegate)? (或 : how to speed up method calls through reflection)

标签 c# reflection delegates unity3d invoke

我知道已经有这样的问题,但我真的不明白答案(而且我似乎无法对它们发表评论)。

我对反射完全陌生,对委托(delegate)也很陌生,所以这对我来说非常困难。

前段时间我(第一次)使用反射得到一个方法,我是这样(简化)的:

object perlinObj;
MethodInfo PerlinMethod = null;    
//...
ConstructorInfo constructor = type.GetConstructor(Type.EmptyTypes);
perlinObj = constructor.Invoke(new object[] { });
PerlinMethod = type.GetMethod("GetValue", new Type[] { typeof(Vector3) });
//...
float PerlinFunction(Vector3 pos)
{
   return (float)((Double)PerlinMethod.Invoke(perlinObj, new object[] { pos }));
}

这可行,但问题是它比直接调用该方法慢很多。 所以我想,也许我可以以某种方式将它分配给委托(delegate),然后调用委托(delegate)而不是使用 invoke,我认为这会更快。 (是的,对吧?)

但是我找不到如何做到这一点。 我不明白 msdn 上的文档:http://msdn.microsoft.com/en-us/library/ms228976.aspx (我什至不确定他们做的和我想做的一样), 我也不明白我必须通过阅读这个来做什么:Assign method to delegate through reflection .

(我试过没用)

那么谁能向我解释一下我必须在我提供的示例代码中做什么?

最佳答案

要以“简单”的方式做到这一点,您需要比 object 更准确地了解目标;即代替:

object perlinObj;

你需要:

SomeType perlinObj;

然后,我们使用 Delegate.CreateDelegate 来创建委托(delegate),而不是存储 MethodInfo - 注意我在这里使用 int为方便起见 Vector3 的位置:

Func<SomeType, int, float> PerlinMethod;
//...
PerlinMethod = (Func<SomeType, int, float>) Delegate.CreateDelegate(
        typeof(Func<SomeType, int, float>),
        null,
        type.GetMethod("GetValue", new Type[] { typeof(int) }));
//...
float PerlinFunction(int pos)
{
    return PerlinMethod(perlinObj, pos);
}

注意,如果目标实例永远不会改变,你可以简化:

Func<int, float> PerlinMethod;
//...
PerlinMethod = (Func<int, float>) Delegate.CreateDelegate(
        typeof(Func<int, float>),
        perlinObj,
        type.GetMethod("GetValue", new Type[] { typeof(int) }));
//...
float PerlinFunction(int pos)
{
    return PerlinMethod(pos);
}

如果你做不到,那么就需要使用更高级的元编程; ILGeneratorExpression:

Func<object, int, float> PerlinMethod;
//...
var target = Expression.Parameter(typeof(object));
var arg = Expression.Parameter(typeof(int));
var call = Expression.Call(
    Expression.Convert(target, type),
    type.GetMethod("GetValue", new Type[] { typeof(int) }),
    arg);

PerlinMethod = Expression.Lambda<Func<object,int,float>>(
    call, target, arg).Compile();

关于c# - 如何将通过反射获得的方法分配给委托(delegate)? (或 : how to speed up method calls through reflection),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19539871/

相关文章:

c# - ASP.NET MVC ActionLink 没有选择正确的 Controller

c# - 具有XML数据源的Ext.NET GridPanel

Swift 函数文本字段获得焦点 OSX

c# - 泛型中的多态性 - 传递继承对象时出现编译错误(无法隐式转换类型)

Java:使用反射转储对象信息时如何避免循环引用?

Java Hashmap 仅在键中存储特定类型的值

c# - 如何使用反射实例化对象构造函数中的属性

c# - 不带参数的委托(delegate)

c# - 委托(delegate)参数

c# - 在 C# 中获取最后 'N' 个季度