pro*_*eek 5 .net c# reflection delegates
由于被要求在这个岗位,我想出了一个使用委派用来加快在.NET/C#恢复体力的例子.
但是,运行时出现此错误(编译工作正常).可能有什么问题?
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 <filename unknown>:0
at System.Delegate.CreateDelegate (System.Type type, System.Reflection.MethodInfo method, Boolean throwOnBindFailure) [0x00000] in <filename unknown>:0
at System.Delegate.CreateDelegate (System.Type type, System.Reflection.MethodInfo method) [0x00000] in <filename unknown>:0
at EX.RefTest.DelegateTest () [0x00000] in <filename unknown>:0
at EX.RefTest.Main () [0x00000] in <filename unknown>:0
Run Code Online (Sandbox Code Playgroud)
这是(工作)源代码,感谢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<int, int, int>), 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<int, int, int> sum = (Func<int, int, int>) Delegate.CreateDelegate(typeof(Func<int, int, int>), h, m);
res = sum(100, 200);
Console.WriteLine("{0}", res);
}
static void Main()
{
DelegateTest();
}
}
}
Run Code Online (Sandbox Code Playgroud)
根据Jon的回答,我做了一些性能测试,使用总和1000次.与使用方法相比(int) call.DynamicInvoke(new object[] {100, 200});,Func<int, int, int> sum = (Func<int, int, int>) Delegate.CreateDelegate(typeof(Func<int, int, int>), h, m);快300倍.
Hello不是委托类型 - 因此您不能将其Delegate.CreateDelegate作为第一个参数传递给它.您需要具有相同参数类型和返回类型的委托类型 - 在这种情况下,类似于:
delegate int Foo(int x, int y);
Run Code Online (Sandbox Code Playgroud)
要么
Func<int, int, int>
Run Code Online (Sandbox Code Playgroud)
另请注意,Delegate.CreateDelegate您调用的重载意味着用于静态方法 - 您应该使用重载,该重载也接受委托的目标(在本例中h).
我有一篇博客文章,显示Delegate.CreateDelegate用于加快访问速度.请注意,我不希望DynamicInvoke比使用反射直接调用方法快得多...它仍然需要检查参数类型等.真的你想要一个静态调用的强类型委托类型(而不是动态)使事情变得非常快.