.NET将类解析为错误的DLL

我的C#项目引用了两个第三方DLL。 这很重要,因为这意味着我无法访问源代码,也无法修改或重新编译这两个DLL。

让我们称他们为dll A和dll B.这是dll A的样子:

namespace ThirdParty.Foo { public class Bar { ...snip... } public class Something { public Bar MyProperty { get; set; } } } 

这就是dll B的样子:

 namespace ThirdParty.Foo { public class Bar { ...snip... } public class SomethingElse { public Bar MyProperty { get; set; } } } 

如您所见,它们具有相同的命名空间,并且它们都定义了具有相同名称的类。 我的C#代码需要引用这两个DLL。 我在引用上使用alias属性能够区分两个引用,并且我还在我的C#文件顶部使用extern alias firstDllextern alias secondDll 。 到现在为止还挺好。

对我来说很明显, Something.MyProperty的类型是firstDll.ThirdParty.Foo.Bar,而SomethingElse.MyProperty的类型是secondDll.ThirdParty.Foo.Bar但是由于某种原因,Visual Studio会混淆并解析两者的类型firstDll中相同Bar类的属性。

有没有办法让我“强制”VisualStudio来解析正确的类型?

编辑:我在Visual Studio中得到的错误是:无法将类型’ThirdParty.Foo.Bar [d:\ MySolution \ References \ Second.dll]’隐式转换为’ThirpParty.Foo.Bar [d:\ MySolution \ References \ First.dll]”

创建一个DLL作为DLL A的包装器。让我们调用新的DLL“C”。 然后您的项目将引用DLL B和C.

如果这两种类型具有相同的名称和命名空间,那么您就会陷入困境。 在C#中,名称/标识符非常重要,“最适合”仅适用于特殊情况。

但是,您可以为两种不同的类型编写包装器,并使这些包装器具有不同的名称。 通过为包装器提供两个不同的(甚至一个)项目,您可以只有一个引用,从而有效地“通过强制”解决冲突。

有效的东西(对我来说它确实正确引用)如下,首先(你可能已经做过)点击引用中的每个dll并分配一个别名并放置正确的extern别名。之后使用类Something和SomethingElse(和正确分配Bar Property)为每个类创建一个类(Something和SomethingElse)并从它们派生并遮蔽MyProperty属性:

 public class TestFirst : first.ThirdParty.Foo.Something { //here you shadow and since you must provide the alias //and the fully qualified name it will bet set to the //right Bar class,same bellow in testsecond. public first.ThirdParty.Foo.Bar MyProperty { get; set; } } public class TestSecond : second.ThirdParty.Foo.SomethingElse { public second.ThirdParty.Foo.Bar MyProperty { get; set; } } 

正常业务之后:

 TestSecond t = new TestSecond(); t.MyProperty = new second.ThirdParty.Foo.Bar(); 

我会通过Assembly.Load显式加载dll然​​后对你需要的类型做一个createinstance然后通过动态调用方法 – 那是因为我很懒。 另一种(不是懒惰的)方法是使用reflection来查找方法并调用它。

由于这里有一个极端情况,两个程序集不仅具有相同的命名空间,而且具有相同的完整程序集名称(意味着类型具有相同的程序集限定名称),您可能需要考虑更极端的措施来解决它。 如果它是一个完全托管的DLL(没有混合使用的本机代码)并且没有强名称(或者您可以删除强命名),您可以使用以下过程:

  1. 运行ildasm并输出到磁盘上的.il文件。
  2. 使用仔细搜索修改.il文件并替换以更改所有类型的根命名空间(对内部命名空间或包含与根命名空间相同的文本的类型名称要小心。)
  3. 通过ilasm运行修改后的文件,以构建带有更改的新.dll。

您可以使用关键字var而不是显式指定类型以避免模糊引用

 var x = new ThirdParty.Foo.Something(); var y = new ThirdParty.Foo.SomethingElse(); var barX = x.MyProperty; var barY = y.MyProperty; 

我以前注意到IntelliSense在某些情况下无法区分不同的类型。 到目前为止,我遇到过两次这个问题:

  1. 我的项目包括对SQL Server 2008和2012版Microsoft.SqlServer.Types.dll程序集引用; 使用extern alias在源代码中区分。 Intellisense无法解决这个问题。

    这大致就是你要问的问题。

  2. 当类型名称仅在某些重音或变音符号上有所不同时,例如StatusStatūs 。 智能感知无法将它们可靠地识别为单独的类型,并且只能显示一个。 我记得由于自动类型推断,问题可以部分避开。

我还没有找到解决这些问题的完整解决方案。 我认为它们是Intellisense / Visual Studio的缺点或缺陷,微软应该修复它们(如果它们尚未在VS的后续版本中修复)。