今天,我仔细研究了VisualStudio2010中程序集引用的"特定版本"属性.经过几次意想不到的实验后,我开始尽可能多地了解这个属性是如何工作的.即便如此,在我看来,并不是所有的答案,所以我试图self 回答这个问题:

exactly程序集引用的"特定版本"属性在Visual Studio中是如何工作的?

推荐答案

它是编译时属性!

需要知道的最重要的事情之一是,"特定版本"是一个在运行时compile-timenot生效的属性.

这是怎么回事?

生成项目时,需要解析项目的程序集引用,以便找到生成系统应该使用的物理程序集.如果执行了"特定版本"判断(请参阅"何时判断特定版本?"),它影响大会决议过程的结果:

  • 生成系统定位它可能使用的物理程序集
  • 生成系统将物理程序集的版本与存储在中的程序集版本进行比较.csproj文件,供组件参考
  • 如果两个程序集版本完全相同,则解析过程成功,并将找到的物理程序集用于生成
  • 如果两个程序集版本不匹配,则丢弃物理程序集,并通过定位下一个潜在程序集继续解析过程
  • 如果找不到更多潜在的物理组件,解析过程将失败.这将导致编译器警告(警告MSB3245),告诉您无法解析引用.
  • 有趣的是,如果代码没有对程序集的实际引用,则生成成功(带有前面提到的警告).如果代码有引用,则生成会失败,并出现一个错误,看起来代码使用的是未知类型或名称空间.生成really失败的唯一原因是警告MSB3245.

解析程序集的顺序

部件解析过程查找潜在部件的顺序如下:

  1. 由.csproj文件中的<HintPath>元素引用的程序集
  2. 项目输出路径
  3. GAC

请注意,如果GAC中存在多个版本的程序集,则解析过程首先try 解析为具有最高版本的程序集.只有在未进行"特定版本"判断时,这一点才很重要.

何时判断"特定版本"?

VisualStudio根据在中找到的两条信息决定是否执行"特定版本"判断.csproj文件:

  • <SpecificVersion>元素的存在或不存在及其值(如果存在)
  • 程序集引用中是否存在版本信息

带有版本信息的典型程序集引用如下所示:

<Reference Include="Foo, Version=1.2.3.4, Culture=neutral, processorArchitecture=MSIL">
  <SpecificVersion>True</SpecificVersion>
  <HintPath>..\..\Bar\Foo.dll</HintPath>
</Reference>

以下是程序集引用的without个版本信息:

<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>和版本信息都不存在,则不会执行任何判断( case 6).我预计判断将被执行并且总是失败(与 case 2相同),因为在我的理解中,缺少<SpecificVersion>意味着缺省值"True".这可能是Visual Studio2010的一个怪癖,我在那里进行了测试.

在Visual Studio UI中判断程序集引用的属性时( Select 引用并点击F4),您看到的"特定版本"属性的值会告诉您Visual Studio是否要执行"特定版本"判断.在 case 6中,用户界面将显示"True",尽管<SpecificVersion>元素不在列表中.csproj文件.

"复制本地"的副作用

如果"Copy Local"属性设置为"True",但程序集解析过程由于"Specific Version"判断而失败,则不复制任何程序集.

标准物质

.net相关问答推荐

.NET Blazor-使用子组件中的处理程序方法进行双向数据绑定

Azure管道-使用.NET 8 RC2 SDK生成C#项目失败

使用CLR将数据从Excel导入SQL Server时出错

如何将 signalR 添加到不同项目中的后台服务?

为什么脚本不从 _Layout 加载并且必须添加到部分视图中?

更改列表中的值

为什么(真的吗?)List 实现所有这些接口,而不仅仅是 IList

如何使用 C# 关键字作为属性名称?

使用字典作为数据源绑定组合框

图像与位图类

如何使用反射在 .NET 中调用重载方法

C# 编译为 32/64 位,或任何 cpu?

如何制作通用类型转换函数

多个添加的实体可能具有相同的主键

获取 .NET 程序集的 AssemblyInformationalVersion 值?

在 .NET 中获取默认打印机的最佳方法是什么

在 .Net 中调用 Web 服务时绕过无效的 SSL 证书错误

System.Array.CopyTo() 和 System.Array.Clone() 之间的区别

.NET Remoting 真的被弃用了吗?

名称 <...> 不存在于命名空间 clr-namespace <...>