.net “的目的是什么?”;删除未使用的引用“;

.net “的目的是什么?”;删除未使用的引用“;,.net,visual-studio,compiler-construction,reference,.net,Visual Studio,Compiler Construction,Reference,我已经读到,删除对编译器的未使用引用会忽略代码本身中未引用的程序集 但我觉得很难相信,因为这样的话,它的真正目的是什么?它对生成的程序集的大小或其他方面没有任何明显的影响。或者这种智能行为是否仅限于C#编译器(csc.exe),而不是vbc.exe固有的 如果这个功能是如此无用,为什么要提供它作为一个功能?为什么在VisualStudio项目配置对话框中提供它 我能想到的唯一有用的活动是在部署期间。安装程序仍将复制引用(已使用或未使用)。但是对于驻留在GAC中的程序集(例如,BCL程序集),这也

我已经读到,删除对编译器的未使用引用会忽略代码本身中未引用的程序集

但我觉得很难相信,因为这样的话,它的真正目的是什么?它对生成的程序集的大小或其他方面没有任何明显的影响。或者这种智能行为是否仅限于C#编译器(csc.exe),而不是vbc.exe固有的

如果这个功能是如此无用,为什么要提供它作为一个功能?为什么在VisualStudio项目配置对话框中提供它


我能想到的唯一有用的活动是在部署期间。安装程序仍将复制引用(已使用或未使用)。但是对于驻留在GAC中的程序集(例如,BCL程序集),这也不会是一个问题。

除了源文件更小之外,我认为最好有一个没有未使用的代码或引用的干净源文件。

Visual Studio 2008还具有使用指令删除未使用的功能


删除未使用的代码可以使代码更整洁,但也可以降低冲突的风险。有时,不同程序集中存在同名的类。例如,在
System.Drawing
System.Web.UI.WebControls
中都有一个
Image
类。如果您对这两个名称空间都有using指令,并且开始使用Image类,那么编译器无法判断要使用哪一个。

这是一种优化,可以使您的项目编译更快。它避免了编译器加载永远不会使用的元数据。这是一个小问题,但我猜大约50毫秒,这取决于你的硬盘速度和文件系统缓存状态


C#编译器足够聪明,只在编译的程序集元数据中为实际使用的程序集发出.assembly引用。因此,您不会为运行Ngen.exe时不使用的程序集生成本机映像。JIT编译器不会受到任何影响,它只根据需要加载程序集以转换IL。

它防止CLR在运行时加载引用的模块。这将减少启动时间(因为加载每个模块需要时间)。根据模块的大小,它可能会显著缩短启动时间

测试这一点的一种方法是创建一个测试WinForms项目,添加对未使用的程序集的引用(例如System.Web),然后运行并附加到可执行文件(例如F5)。查看加载的模块(调试->窗口->模块),您将看到引用的程序集已加载


如果您仔细想想,CLR将很难确定是否真的使用了依赖项(一旦添加了对它的引用,它就作为依赖项出现在清单中)。。。特别是由于某些代码路径的执行无法提前知道…

Visual Studio 2010的参考助手是删除应用程序中未使用参考的最佳工具


谢谢你,克里斯托弗,但问题仍然是。。。它如何/为什么更好?它更好,因为您的源文件不会膨胀,不会使用未使用的代码/导入,因此更易于阅读和理解。此外,我认为编译器将有更少的工作要做,编译将是一个稍微快一点。(我不是100%确定,这是特定于编译器的)这是否意味着当加载一个NGENed程序集时,所有引用的程序集也会随后加载?或者换句话说:本机程序集的延迟加载是不可能的?至少在比较应用程序加载的程序集(JITed与NGEND)时,我看到了这一点。CLR将如何在运行时加载其引用已被编译器优化删除的模块?我在这里遗漏了什么?@Dan-我也不明白为什么这个答案得到了这么多赞成票,从我在其他帖子上读到的情况来看,如果不使用汇编引用,编译器不会将其放入最终输出中。引用的程序集仅在第一次调用它们的方法时由JIT加载。此答案作为证明带来的loaded modules(已加载模块)窗口可能会显示所有引用,因为它处于调试模式。@BornToCode另外,如果CLR很难确定是否确实使用了依赖项,那么“删除未使用的引用”是如何工作的?确定是否使用引用很简单:如果没有代码引用该程序集命名空间中的任何内容,则该程序集未使用。