【发布时间】:2023-04-04 04:35:01
【问题描述】:
我意识到,一般来说,使用反射会影响性能。 (实际上,我自己根本不喜欢反思;这是一个纯粹的学术问题。)
假设存在一些如下所示的类:
public class MyClass {
public string GetName() {
return "My Name";
}
}
请耐心听我说。我知道如果我有一个名为x 的MyClass 实例,我可以调用x.GetName()。此外,我可以将Func<string> 变量设置为x.GetName。
现在这是我的问题。假设我不知道上面的类叫做MyClass;我有一些对象,x,但我不知道它是什么。我可以通过这样做来检查该对象是否具有GetName 方法:
MethodInfo getName = x.GetType().GetMethod("GetName");
假设getName 不为空。那么我不能进一步检查getName.ReturnType == typeof(string) 和getName.GetParameters().Length == 0,在这一点上,我不能确定我的getName 对象所代表的方法可以肯定转换为Func<string>,不知何故?
我意识到有一个MethodInfo.Invoke,我也意识到我总是可以创建一个Func<string>,比如:
Func<string> getNameFunc = () => getName.Invoke(x, null);
我想我要问的是是否有任何方法可以从 MethodInfo 对象到它所代表的实际方法,从而产生反射的性能成本在进程中,但是在之后能够直接调用方法(例如,通过Func<string>或类似的东西)没有性能损失。
我的设想可能是这样的:
// obviously this would throw an exception if GetActualInstanceMethod returned
// something that couldn't be cast to a Func<string>
Func<string> getNameFunc = (Func<string>)getName.GetActualInstanceMethod(x);
(我意识到这不存在;我想知道是否有任何类似的东西。)
【问题讨论】:
-
在您编辑的 cmets 上 - 您会看到使用此类解决方案的速度大幅提升,因为动态编译的委托和静态编译的委托之间几乎没有区别;一旦排除了编译的开销。自从我“发现”了表达式树的东西以来,我一直在到处使用它们,并且可能会将其作为我在 .Net 3.5 中的#1 功能。在 v4 中它甚至更好,因为您可以编写多语句代码 - 因为 DLR 需要扩展而需要。
标签: .net performance reflection methodinfo func