C# VS2008 编译器选择错误的方法
Posted
技术标签:
【中文标题】C# VS2008 编译器选择错误的方法【英文标题】:C# VS2008 Compiler picking up wrong Methods 【发布时间】:2011-01-27 10:59:25 【问题描述】:我在 VS2008 中构建项目时遇到了一个非常奇怪的问题。在进行了一些完全不相关的更改后,我开始遇到构建错误。基本上编译器会选择不正确的扩展方法。
Assembly1:引用 Assembly4。
[DebuggerHidden]
public static List<T> ToList<T>(this IEnumerable<T> source)
[System.Runtime.InteropServices.ComVisible(false), CLSCompliant(false)]
public static List<T> ToList<T>(this IConcreteCollection collection)
Assembly3:仅引用 Assembly1。请注意,CustomClass 没有实现 IConcreteCollection。
List<CustomClass> list = new CustomClass[].ToList();
Assembly4: IConcreteCollection 已定义。
错误信息:
类型 'Assembly4.Namespace.IConcreteCollection' 是 在未定义的程序集中定义 参考。您必须添加参考 组装 'Assembly4.Namespace, Version=...'。
如您所见,尽管类型不匹配,但 Assembly3 错误地尝试在 Assembly1 中使用错误的扩展。
VS2008 goto-definition 可以正常工作并指向 Assembly1 中的正确方法。
其他人遇到过这种情况或知道可能是什么问题吗?
【问题讨论】:
IConcreteCollection 在哪里定义?如果您可以给出一个包含所有三个程序集中类型的完整示例,那将有所帮助。 @Jon:抱歉。 IConcreteCollection 将在另一个程序集中定义(因此 Assembly4),在本示例中仅由 Assembly2 引用。 那么 anything 是否引用了 Assembly2?这听起来很奇怪,但一个完整的例子真的很有帮助。如果你做了一个完全干净的构建,那能解决它吗? @Jon:我查看了是否有任何东西引用了 assembly2 并在我的示例中发现了一个错误。不同的命名空间相同的程序集:S。两种扩展方法实际上都在同一个程序集中(对此感到抱歉)。然而,Assembly3 对 IConcreteCollection 一无所知。完全重建并不能解决问题。 【参考方案1】:好的,现在您已经更新了问题,这个错误非常有意义。如果您要在 Assembly1 中拥有一个引用 Assembly4 中的类型的公共方法,那么使用该方法 Assembly1 的任何人可能都需要对 Assembly4 的引用。基本上,编译器会查看候选方法,并没有足够的知识来决定它是否适用。
只需从 Assembly4 添加对 Assembly3 的引用,一切都会好起来的。如果您不想想要添加该引用,则应更改其中一种方法的名称,或将其设为内部/私有。不要让编译器检查它不理解的签名:)
【讨论】:
嗯,我理解这种情况下的行为。我认为我们可以确定我们在 VS 中的类型并且有点期望编译器能够处理这种情况有点奇怪,但我明白为什么它可能是一个限制。我已经解决了这个问题,因为在这种情况下,那些大会应该彼此不可知。感谢您花时间回答。 @Ian:想象一下,如果IConcreteCollection
是一个从 CustomClass[]
进行用户定义转换的类型 - 这并非不可能......以上是关于C# VS2008 编译器选择错误的方法的主要内容,如果未能解决你的问题,请参考以下文章
VS2008 编译时出现的错误:无法打开编译器中间文件。如何解决?