问题描述
正如此post,我想出了一个使用 Delegate 来加速 .NET/C# 中的反射的示例.
As is asked in this post, I came up with an example that uses Delegate to speedup Refection in .NET/C#.
但是,我在运行时遇到了这个错误(编译工作正常).可能有什么问题?
However, I got this error when running (compilation works fine). What might be wrong?
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
添加
感谢 Jon & 的帮助,这是(工作的)源代码ChaosPandion.
ADDED
This is the (working) source code thanks to the help from 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();
}
}
}
添加2
根据 Jon 的回答,我做了一些性能测试以使用 sum 1000 时间.相比使用(int) call.DynamicInvoke(new object[] {100, 200});
的方法,Func
ADDED2
Based on Jon's answer, I did some performance test to use sum 1000 time.
Compared to the method of using (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);
is 300 times faster.
推荐答案
Hello
不是委托类型 - 所以你不能将它传递给 Delegate.CreateDelegate
作为第一个论点.您需要一个具有相同参数类型和返回类型的委托类型 - 在这种情况下,类似于:
Hello
isn't a delegate type - so you can't pass it into Delegate.CreateDelegate
as the first argument. You need a delegate type with the same parameter types and return type - in this case, something like:
delegate int Foo(int x, int y);
或
Func<int, int, int>
还请注意,您调用的 Delegate.CreateDelegate
的重载旨在用于 static 方法 - 您应该使用也需要的重载委托的目标(在本例中为 h
).
Also note that the overload of Delegate.CreateDelegate
you've called is meant to be used for a static method - you ought to be using the overload which also takes the target of the delegate (in this case, h
).
我有一篇博文 显示使用 Delegate.CreateDelegate
来加快访问速度.请注意,我不希望 DynamicInvoke
比直接使用反射调用方法快得多......它仍然需要检查参数类型等.真的你想要一个强类型的委托类型静态调用(而不是动态调用)以使事情变得非常快.
I have a blog post which shows using Delegate.CreateDelegate
for speeding up access. Note that I wouldn't expect DynamicInvoke
to be significantly faster than calling the method directly with reflection... it's still going to have to check the parameter types etc. Really you want a strongly-typed delegate type called statically (as opposed to dynamically) to make things really fast.
这篇关于示例:在 .NET/C# 中使用委托加速反射 API的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!