【问题标题】:Why same namespace errors for Linq methods?为什么 Linq 方法出现相同的命名空间错误?
【发布时间】:2018-02-23 22:53:13
【问题描述】:

我已经重构了我的小项目,以更正命名空间和类名。在此过程中的某个地方,出现了一些问题,我得到了一个与 Linq 方法相关的编译错误,直到我用 ObservableCollection 类文件中的随机命名空间修复它。 linq 错误仅与 ObservableCollection 相关,与 winform 中的任何其他对象无关。

这感觉像是一个 Visual Studio 错误,因为我觉得我已经检查了所有内容。

我在同一个项目中有一个winform、一个类(MyObject)和另一个类(ObservableCollection)。

它们都具有对 System.Linq 的引用,并且都具有 MyProject.ProjectCategory 的命名空间

winform 是这样的

using System.Linq;
namespace MyProject.ProjectCategory
private ObservableCollection<MyObject> myList;

// ...later in a method
myList.All(f => f.Title != "Test")

// the list of errors contains any Linq methods and is a long list. Here is one example
// ERROR: MyProject.ProjectCategory.ObservableCollection<MyObject> does not contain 
// a definition for 'All' and no extension method 'All' accepting the first argument  
// of type MyProject.ProjectCategory.ObservableCollection<MyObject>

如果我更改类的命名空间(ObservableCollection),以下是结果

MyProject.ProjectCategory (as above) ERROR
MyProject ERROR
Fubar COMPILES
MyProject.ProjectCategory.Fubar COMPILES

我已尝试清理、重建、删除所有 bin 和 obj 文件夹。检查所有 .Net 版本号都相同。检查参考路径。

我可以使用和 Fubar 命名空间,但如果有人有线索,我会进行修复。

【问题讨论】:

  • 你在MyProject中有一个扩展方法叫All吗?更改命名空间时可能不会重命名的名称?
  • @RonBeyer 进行了搜索,否。但是在包含我的自定义 linq 扩展的引用项目中还有另一个类文件,但该命名空间仍为 System.Linq,并且在 All 中没有扩展那个。更清楚地说,All 只是一个例子,我得到了许多不同 linq 表达式的错误,Find,Where 等
  • 有时会出现编译器错误,但“我觉得我已经检查了所有内容但我无法弄清楚”并不是编译器错误的证据。这证明你的感觉是错误的。 制作一个小而完整的程序来重现问题。这样做,您将有 99% 的可能自己发现问题。如果你不这样做,那么把它贴在这里,有人会告诉你你做错了什么。
  • 你的 ObservableCollection 实现 IEnumerable 了吗?
  • 阅读我的回答;更改命名空间会更改您的 winform 中的非限定名称 ObservableCollection 解析为的类型。您对ObservableCollection&lt;T&gt; 的实现未实现IEnumerable&lt;T&gt;,编译器无法解析对任何有效扩展方法的调用。当您更改命名空间时,相同的非限定名称会解析为实现 IEnumerable&lt;T&gt; 的其他类型,并且扩展方法会正确解析。

标签: c# visual-studio linq visual-studio-2013


【解决方案1】:

您的ObservableCollection&lt;T&gt; 没有实现IEnumerable&lt;T&gt;。 Linq 扩展方法只能应用于实现接口的对象:

 public static bool All<T>(this IEnumerable<T>, .... )
 public static IEnumerable<T> Where<T>(this IEnumerable<T>, .... )
 public static T First<T>(this IEnumerable<T>, ...)
 etc.

您还必须了解命名空间的工作原理。考虑以下可怕的命名空间示例,只是为了说明您的问题:

//using System; intentionally commented out

namespace System.Foo
{
     class Foo
     {
         String s; //huh? Why is System.String addressable with 
                   //unqualified name?
}

这里发生的情况是,当您一个命名空间A.B 块中时,它会自动允许您引用命名空间A.B 中定义的所有类型 A 没有完全限定他们的名字。

根据您的具体情况,这意味着当您的ObservableCollection&lt;T&gt; 定义在命名空间MyProject.ProjectCategoryMyProject 中时,winform 中的名称ObservableCollection 指的是该类型 并且无法解析扩展方法调用。

但是,当您将 ObservableCollection&lt;T&gt; 的命名空间更改为 FubarMyProject.ProjectCategory.Fubar 时,winform 内的名称 ObservableCollection&lt;T&gt; 将停止引用您的实现,编译器会将其解析为其他类型(可能System.Collections.ObjectModel.ObservableCollection&lt;T&gt;),确实实现了IEnumerable&lt;T&gt;,并且所有 linq 扩展方法突然开始工作。

【讨论】:

  • 这行得通! public class ObservableCollection&lt;T&gt; : System.Collections.ObjectModel.ObservableCollection&lt;T&gt;, INotifyPropertyChanged感谢您在回答中提供的线索和解释
  • @Valamas-AUS 您似乎对这里发生的事情有一个基本的误解。你应该先看看 C# 的初学者课程,如果你想学习,什么是命名空间。
猜你喜欢
  • 2018-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-10
  • 2019-02-18
相关资源
最近更新 更多