示例:使用.NET / C中的委托加速Reflection API#

正如本文中所提到的 ,我想出了一个使用Delegate加速.NET / C#中的Refection的示例。

但是,运行时出现此错误(编译工作正常)。 可能有什么问题?

Unhandled Exception: System.ArgumentException: type is not a subclass of Multicastdelegate at System.Delegate.CreateDelegate (System.Type type, System.Object firstArgument, System.Reflection.MethodInfo method, Boolean throwOnBindFailure, Boolean allowClosed) [0x00000] in :0 at System.Delegate.CreateDelegate (System.Type type, System.Reflection.MethodInfo method, Boolean throwOnBindFailure) [0x00000] in :0 at System.Delegate.CreateDelegate (System.Type type, System.Reflection.MethodInfo method) [0x00000] in :0 at EX.RefTest.DelegateTest () [0x00000] in :0 at EX.RefTest.Main () [0x00000] in :0 

添加

这是(工作)源代码,感谢Jon&ChaosPandion的帮助。

 using System.Reflection; using System; namespace EX { public class Hello { // properties public int Valx {get; set;} public int Valy {get; set;} public Hello() { Valx = 10; Valy = 20; } public int Sum(int x, int y) { Valx = x; Valy = y; return (Valx + Valy); } } public class RefTest { static void DelegateTest() { Hello h = new Hello(); Type type = h.GetType(); MethodInfo m = type.GetMethod("Sum"); // Wrong! Delegate call = Delegate.CreateDelegate(type, m); Delegate call = Delegate.CreateDelegate(typeof(Func), h, m); int res = (int) call.DynamicInvoke(new object[] {100, 200}); Console.WriteLine("{0}", res); // This is a direct method implementation from Jon's post, and this is much faster Func sum = (Func) Delegate.CreateDelegate(typeof(Func), h, m); res = sum(100, 200); Console.WriteLine("{0}", res); } static void Main() { DelegateTest(); } } } 

ADDED2

根据Jon的回答,我做了一些性能测试,使用总和1000次。 与使用(int) call.DynamicInvoke(new object[] {100, 200});Func sum = (Func) Delegate.CreateDelegate(typeof(Func), h, m); 快了300倍。

Hello不是委托类型 – 因此您不能将其作为第一个参数传递给Delegate.CreateDelegate 。 您需要具有相同参数类型和返回类型的委托类型 – 在这种情况下,类似于:

 delegate int Foo(int x, int y); 

要么

 Func 

另请注意,您调用的Delegate.CreateDelegate的重载意味着用于静态方法 – 您应该使用也会占用委托目标的重载(在本例中为h )。

我有一个博客文章 ,显示使用Delegate.CreateDelegate加速访问。 请注意,我不希望DynamicInvoke比直接用reflection调用方法快得多……它仍然需要检查参数类型等。真的你想要一个静态调用的强类型委托类型(而不是动态的) )让事情变得非常快。

您需要指定委托的类型并绑定this参数。

 Delegate call = Delegate.CreateDelegate(typeof(Func), h, m); 

你也可以使用:

 m.Invoke(null, new object[] { 100, 200 }); 

它不会引起我一直处理的任何性能问题。