示例:使用.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 });
它不会引起我一直处理的任何性能问题。
- 如何从C#代码进入SQL Server存储过程?
- 警告:“…覆盖Object.Equals(对象o)但不覆盖Object.GetHashCode()”
- 在视图中渲染包含剃刀代码的字符串
- 如何在C#中实现BN_num_bytes()(和BN_num_bits())?
- EF 6 – 如何正确执行并行查询
- HttpContext在global.asax.cs中不起作用
- 是否可以将两个重叠的PictureBox控件与透明图像一起使用?
- 为什么无法捕获MissingMethodException?
- “System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy”类型中的方法“ExecuteAsync”没有实现