如何解决程序集引用的“特定版本”属性在 Visual Studio 中究竟是如何工作的?
这是一个编译时属性!
在运行时生效的属性。
这是什么一回事呢?
构建项目时,需要解析项目的程序集引用,以便找到构建系统应使用的物理程序集。如果执行“特定版本”检查(参见“何时检查“特定版本”?”一节),它会影响程序集解析过程的结果:
- 构建系统定位它可能使用的物理程序集
- 构建系统将物理程序集的版本与存储在 .csproj 文件中的程序集版本进行比较,以供程序集参考
- 如果两个程序集版本完全相同,则解析过程成功,找到的物理程序集用于构建
- 如果两个程序集版本不匹配,则丢弃物理程序集并通过定位下一个潜在程序集继续解决过程
- 如果无法找到更多潜在的物理程序集,则解析过程将失败。这会导致编译器警告(警告 MSB3245)告诉您无法解析引用。
- 有趣的是, 如果代码没有对程序集的实际引用,则构建成功(带有前面提到的警告)。如果代码有引用,则构建失败并出现错误,看起来好像代码使用了未知类型或命名空间。 构建真正 失败的唯一迹象是警告 MSB3245。
解决装配的顺序
程序集解析过程定位潜在程序集的顺序如下所示:
-
<HintPath>
.csproj 文件中的元素引用的程序集 - 项目输出路径
- 海关总署
请注意,如果 GAC 中存在多个版本的程序集,则解析过程首先尝试解析为具有最高版本的程序集。仅当未进行“特定版本”检查时,这一点才重要。
什么时候检查“特定版本”?
Visual Studio 根据 .csproj 文件中的两条信息决定是否执行“特定版本”检查:
- 元素的存在与否
<SpecificVersion>
,及其值(如果存在) - 程序集引用中是否存在版本信息
这是带有版本信息的典型程序集引用的样子:
<Reference Include="Foo, Version=1.2.3.4, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>True</SpecificVersion>
<HintPath>..\..\Bar\Foo.dll</HintPath>
</Reference>
这就是没有 版本信息的程序集引用的样子:
<Reference Include="Foo">
[...]
下表显示了何时执行“特定版本”检查,何时不执行。
| Version information
| Present Not present
-------------------+------------------------------
<SpecificVersion> |
- Present(=True) | 1.Yes 2.Yes (check always fails)
- Present(=False) | 3.No 4.No
- Not present | 5.Yes 6.No
这里令人惊讶的是,如果<SpecificVersion>
不存在版本信息和版本信息,则不执行任何检查(案例
6)。我本来希望执行检查并且总是失败(与情况2相同),因为在我的理解中,缺少<SpecificVersion>
意味着默认值“True”。这可能是我进行测试的
Visual Studio 2010 的一个怪癖。
当您在 Visual Studio UI 中检查程序集引用的属性时(选择引用并按 F4),您看到的“特定版本”属性值会告诉您 Visual Studio
是否要执行“特定版本”查看。在案例 6 中,UI 将显示“True”,尽管<SpecificVersion>
.csproj 文件中不存在该元素。
“复制本地”的副作用
如果“复制本地”属性设置为“真”,但程序集解析过程由于“特定版本”检查而失败,则不会复制任何程序集。
参考资料
- 关于 VS2005 中引用的程序集你需要了解的内容(blogs.msdn.com 文章)
- .NET 2.0 中用于程序集和版本控制的新功能是什么?(codemag.com 文章复制了上述 MSDN 文章,包括一些关于程序集版本控制的屏幕截图和附加信息)
解决方法
今天,我仔细研究了 Visual Studio 2010
中程序集引用的“特定版本”属性。经过一些意外结果的实验后,我开始尽可能多地了解该属性的工作原理。即使如此,在我看来,也没有所有的答案,所以这是我尝试自我回答这个问题:
程序集引用的“特定版本”属性在 Visual Studio 中 究竟 是如何工作的?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。