不能将Enumerable.Count与List一起使用,编译器假定为List.Count
我还没有注意到这种行为,可能是因为我更喜欢VB.NET中的查询语法,并将查询和执行方法分成不同的语句。
如果我尝试编译以下简单查询:
Dim wordList As List(Of String) = New List(Of String) Dim longWords As Int32 = wordList.Count(Function(word) word.Length > 100)
编译器不喜欢这样,因为他希望List.Count
没有参数:
“Public Readonly Property Count As Integer”没有参数,其返回类型无法编入索引。
如果我将它声明为IEnumerable(Of String)
它按预期工作:
Dim wordSeq As IEnumerable(Of String) = New List(Of String) Dim longWords As Int32 = wordSeq.Count(Function(word) word.Length > 100)
为什么会这样? 什么阻止编译器使用Enumerable
扩展方法Count
而不是ICollection.Count
属性。 请注意,我添加了Imports System.Linq
, Option Strict
和Option Infer
都On
。 我正在使用.NET 4.0(Visual Studio 2010)。
我很困惑因为在C#中这没有问题:
List wordList = new List(); int longWordCount = wordList.Count(word => word.Length > 100);
这是设计 ,引自MSDN :
具有属性的情况更简单:如果扩展方法与其扩展的类的属性具有相同的名称,则扩展方法不可见且无法访问。
在C#中,只有调用属性的方法是使用属性语法(即) instance.PropertyName
,因为在Vb.Net中有两个选项。
Dim list As List(Of String) = New List(Of String)() Dim count = list.Count() //Method 1 Dim count2 = list.Count //Method 2
假设你添加一个没有参数的Count
扩展方法, list.Count()
是什么意思? 它始终优先考虑实例成员,因此它指向Property。
好的, list.Count(Function(s) s.StartsWith("a"))
是什么意思? 在这种情况下,它意味着扩展方法?
那时语言没有一致性,我想设计师故意避免这个function的一致性。
如果你需要扩展方法时转换为IEnumerable,一切都会好的:
Dim longWords As Int32 = CType(wordList, IEnumerable(Of String)).Count(Function(word) word.Length > 100)
或者作为评论中提到的dcastro:
Dim longWords As Int32 = wordList.AsEnumerable.Count(Function(word) word.Length > 100)
AsEnumerable
方法的主要目的之一是在IEnumerable
对象的类型具有优先于LINQ扩展方法之一的成员时使用,因此您应该在调用Count
之前添加对AsEnumerable
调用,删除成员冲突。