AssemblyName.ReferenceMatchesDefinition如何工作?

3

给出以下代码:

  var n1 = new AssemblyName ("TestDll, Version=1.0.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089");
  var n2 = new AssemblyName ("TestDll, Version=2.0.0.2001, Culture=en-US, PublicKeyToken=ab7a5c561934e089");

  Console.WriteLine (AssemblyName.ReferenceMatchesDefinition (n1, n2));
  Console.WriteLine (AssemblyName.ReferenceMatchesDefinition (n2, n1));

为什么这两个检查都会打印“True”?我本以为AssemblyName.ReferenceMatchesDefinition应该考虑程序集名称的版本、区域性和公钥令牌属性的差异,难道不是吗?
如果不是这样,那么ReferenceMatchesDefinition做了什么,而简单名称的比较没有做到呢?
3个回答

4
我已在Microsoft Connect上报告了此问题,并确认其是一个错误:

这确实是API中的一个bug。自2.0 RTM引入以来,它一直存在于产品中。它从未正常工作过。

[...]

您还可以考虑使用API AppDomain.ApplyPolicy(手动AssemblyName比较)。该API涵盖了框架程序集的统一和绑定重定向。 您还可以尝试覆盖非强名称程序集引用。当引用中不存在PublicKeyToken时,只会进行简单名称匹配,其余部分将被忽略。


2

我认为这篇博客文章由张俊峰写的,特别是他链接到的关于程序集标识的早期博客文章。像往常一样,我一个字也不懂。祝你好运!


一个“ReferenceIdentity”与一个“DefinitionIdentity”匹配,当且仅当在“ReferenceIdentity”中指定的所有属性的值与“DefinitionIdentity”中相应属性的值匹配。如果在“ReferenceIdentity”中缺少某个属性,则该属性将与“DefinitionIdentity”中该属性的任何值匹配。例如,“Ref 'name'”与“Def 'name, culture=neutral'”和“Def 'name, culture=en-us'”匹配。但是,“Ref 'name, culture=neutral'”不匹配“Def 'name, culture=en-us'”。 - Fabian Schmied
在CLR中,我们有另一种特殊的比较方法——用于Ref-Def匹配的绑定比较。在特殊的绑定比较上下文中,当ReferenceIdentity不包含任何公钥(标记)时,版本号被忽略。 - Fabian Schmied
然而,我仍然看不出上面给出的版本如何匹配。 - Fabian Schmied
我明白你的意思。CLR使用IAssemblyName :: IsEqual()和ASM_CMPF_IL_ALL标志,如果有帮助的话。对我来说,唯一有意义的Ref-Def匹配方式是当CLR在GAC中没有程序集时探测程序集时进行的匹配。但这应该很简单,只需要显示名称匹配即可。 - Hans Passant

0

2
我已经查看了文档,谢谢。就ReferenceMatchesDefinition而言,我知道这两个名称“解析为同一程序集”,但我不知道这是怎么回事。文档中说:“加载器会解析引用和定义,包括策略评估,然后检查定义是否等于引用。” 我看不出这两个名称如何被视为相等。 - Fabian Schmied

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接