【问题标题】:C# VS2008 Compiler picking up wrong MethodsC# VS2008 编译器选择错误的方法
【发布时间】: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 一无所知。完全重建并不能解决问题。

标签: visual-studio-2008 c#-2.0


【解决方案1】:

好的,现在您已经更新了问题,这个错误非常有意义。如果您要在 Assembly1 中拥有一个引用 Assembly4 中的类型的公共方法,那么使用该方法 Assembly1 的任何人可能都需要对 Assembly4 的引用。基本上,编译器会查看候选方法,并没有足够的知识来决定它是否适用。

只需从 Assembly4 添加对 Assembly3 的引用,一切都会好起来的。如果您不想想要添加该引用,则应更改其中一种方法的名称,或将其设为内部/私有。不要让编译器检查它不理解的签名:)

【讨论】:

  • 嗯,我理解这种情况下的行为。我认为我们可以确定我们在 VS 中的类型并且有点期望编译器能够处理这种情况有点奇怪,但我明白为什么它可能是一个限制。我已经解决了这个问题,因为在这种情况下,那些大会应该彼此不可知。感谢您花时间回答。
  • @Ian:想象一下,如果 IConcreteCollection 是一个从 CustomClass[] 进行用户定义转换的类型 - 这并非不可能......
猜你喜欢
  • 2010-11-24
  • 2023-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-03
  • 1970-01-01
  • 2014-06-02
相关资源
最近更新 更多