C#昂贵的方法调用?Assembly.GetEntryAssembly()和Assembly.GetCallingAssembly()
我刚刚看到这行C代码,我想知道它是否昂贵C#昂贵的方法调用?Assembly.GetEntryAssembly()和Assembly.GetCallingAssembly(),c#,reflection,C#,Reflection,我刚刚看到这行C代码,我想知道它是否昂贵 Assembly assembly = useEntryAssembly ? Assembly.GetEntryAssembly() : Assembly.GetCallingAssembly(); 除非你经常打这样的电话,否则费用是相当小的,我不会为此担心 在我的机器上Assembly.GetEntryAssembly()在调试模式下随机运行时,第一次执行164次计时,第二次执行7次计时。在没有深入反射器的情况下,它似乎正在缓存调用 我的机器上每秒有
Assembly assembly = useEntryAssembly ? Assembly.GetEntryAssembly() : Assembly.GetCallingAssembly();
除非你经常打这样的电话,否则费用是相当小的,我不会为此担心 在我的机器上
Assembly.GetEntryAssembly()
在调试模式下随机运行时,第一次执行164次计时,第二次执行7次计时。在没有深入反射器的情况下,它似乎正在缓存调用
我的机器上每秒有2597734个滴答声,所以164对7仍然不重要。我不知道性能如何,但这是一种代码气味,取决于您将使用此
程序集
对象的目的
由于您可以执行typeof(Anything).Assembly
来查找程序集,因此无需调用这些程序集,您就可以知道自己所在的程序集。编译器可以检查typeof
关键字,而GetEntryAssembly
和GetCallingAssembly
的结果可能会让您大吃一惊。(例如,GetEntryAssembly
可以是null
)
了解您需要从这个程序集中获取哪些信息会有所帮助—可能有更好的方法检索它。除非您经常打这些电话,否则我不会担心。在任何情况下,都可以进行一些简单的优化 例如,
Assembly.GetEntryAssembly()
在进程的生命周期内(对于给定的AppDomain)不会更改,因此无需重复执行此调用,即使您需要访问它。您可以将其替换为:
private static Assembly _entryAssembly;
private Assembly ExecutingAssembly
{
get
{
if (_entryAssembly == null )
{
_assembly = Assembly.GetEntryAssembly();
}
return _entryAssembly
}
现在你不必担心这个电话有多贵;尽管可能,作为另一个回答的评论者,可能框架实际上为您做到了这一点
[注意:这不是一个线程安全的单例-最坏的情况是,如果最初由多个线程同时访问,您会多次调用
Assembly.GetEntryAssembly()
,不值得尝试在这种情况下锁定IMHO]这取决于.NET framework是否已经在缓存。是吗?它藏起来了。Assembly.GetEntryAssembly();我第一次运行它时需要164个滴答声,第二次运行时需要7个滴答声。我的机器上每秒有2597734个滴答声,所以164对7仍然不重要。OP的代码没有得到当前的executin程序集,它得到的是入口程序集(调用堆栈上的顶级程序集)或调用程序集(调用堆栈上的前一个程序集)。我理解OP的代码,但意图不清楚。通常,您的代码知道的足够多,能够以编译器可以检查的方式获得程序集
:即从typeof
。在相对较少的情况下,您的代码真正知道的很少,以至于它只能调用GetEntryAssembly
或GetCallingAssembly
。我不同意。例如,我的所有实用程序类都被其他程序集中的各种其他类调用。有一些类我知道它只在一个调用上下文中使用,但我肯定不会这样假设。在这种情况下,使方法泛型或传递类型
是很有用的。特别是,函数中存在类型
参数,表明该函数将进行反射。让一个方法依赖于调用程序集往往会在单元测试期间崩溃,其中调用程序集通常是动态生成的模拟程序集。完全同意您关于编译器检查的观点,但在这种情况下(不知道更多关于实际用例的情况),考虑到所反映的实际程序集,这很可能是正确的选择。据我们所知,这可能是日志类的一部分,在这种情况下,我认为这是一种合理的方法。