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 编译器选择错误的方法的主要内容,如果未能解决你的问题,请参考以下文章

c# dllimport怎么弱引用

怎样用vs 2008 编译C程序

VS2008 编译时出现的错误:无法打开编译器中间文件。如何解决?

C#程序在VS编译器加载时出现找不到方法,无法显示该程序窗体设计器

VS2008 "无法找到资源编译器dll 请确保路径正确"

vs2008编译错误fatal error C1902: 程序数据库管理器不匹配;请检查安装解决