内部缓存的Type.GetMethod()是否重复调用?

时间:2015-06-03 02:39:52

标签: c# .net reflection

在我的代码中,我有一些函数在CLR的各种静态函数上调用Type.GetMethod(string, Type[])。总共可以查找30个左右的不同静态函数。但是他们经常被反复查找,因为父函数经常被调用。我假设CLR会缓存MethodInfo结果,所以只有第一次调用每个独特的查找方法成本很高,但我想要一些确认。

编辑:MethodInfo结果最终成为Expression.Call()树中Expression语句的参数。

实现自己的缓存会更好/更可靠吗?如果我这样做,我可以在应用程序的最开始一次缓存MethodInfo结果,并且只是无限期地重新访问它们吗?或者我应该使用RuntimeMethodHandle代替:

// Obtaining a Handle from an MemberInfo
RuntimeMethodHandle handle = typeof(D).GetMethod("MyMethod").MethodHandle;
// Resolving the Handle back to the MemberInfo
MethodBase mb = MethodInfo.GetMethodFromHandle(handle);

该片段来自:https://msdn.microsoft.com/en-us/magazine/cc163759.aspx#S8

我不清楚为什么要缓存RuntimeMethodHandle而不只是MethodInfo

1 个答案:

答案 0 :(得分:2)

  

我的问题不是一个快速的调用,因为它确保Type.GetMethod()调用不会在每次使用相同的方法调用时产生大的命中

然后,您需要为给定的方法名称缓存MethodInfo对象。 CLR并不保证它会为您缓存这一点,实际上,无论您多久使用一次,调用GetMethod()都会非常昂贵,具体取决于数据是否仍然被缓存。反射总的来说很昂贵。如果可能的话,应该避免这种情况,尤其是在考虑性能时。

在您的情况下,由于您正在处理Expression个对象,具体取决于您使用它们的确切程度(没有a good, minimal, complete code example,因此无法确定您的方案中哪个最佳),可能会发现缓存已编译的表达式更有意义。更一般地说,显然如果你要缓存任何内容,最有效的方法是将结果缓存到处理缓存密钥不变的处理中。

请注意,CLR 缓存dynamic类型对象的运行时成员解析。如果你不想自己搞乱缓存的实现,你可以将dynamic合并到表达式中,让CLR处理动态命名方法的缓存。同样,如果没有您特定场景的更多详细信息,则无法确定这是否有效,更不用说它是否适用于您的情况。