尝试从Visual Basic使用
Enumerable.Count()扩展方法时,以下代码导致编译时错误:
Imports System.Linq Module Module1 Sub Main() Dim l As New List(Of Foo) From {New Foo("a"),New Foo("b"),New Foo("a")} Dim i As Integer = l.Count(Function(foo) foo.Bar = "a") Console.WriteLine(i) Console.ReadLine() End Sub Class Foo Sub New(ByVal bar As String) Me.Bar = bar End Sub Public Property Bar As String End Class End Module
产生的错误是:
‘Public ReadOnly Property Count As Integer’ has no parameters and its
return type cannot be indexed.
我的目标是.NET 4.0,因此应该支持扩展方法.值得注意的是,C#中的等效代码正确地推断了扩展方法……
为什么编译器无法推断Enumerable.Count的使用,给定我作为参数传递的谓词,以及如何使用扩展方法而不是List的Count属性?
回答你的问题,为什么VB在这种情况下不能做C#所能做的…
VB允许您在名称后使用()访问属性,还可以通过省略()来调用没有参数的函数.索引器也使用圆括号,而不是C#中的方括号.这些是旨在使编程更容易的巨大VB功能的示例,这实际上导致更模糊,更难理解和容易出错的代码.
因此,在这种特殊情况下,VB看到您正在访问Count,并在它是Count属性的索引器之后假定括号,而不是Count函数的参数.
C#看到圆括号,并意识到你没有访问索引器,你必须调用一个函数,所以寻找一个函数.
当然,C#也存在歧义的空间.例如,与扩展方法同名的属性(返回委托类型)将优先于扩展方法调用…
public Action Count { get; set; }
啊……快乐的日子.
至于如何调用IEnumerable.Count()函数,一个强制转换(最好是DirectCast())或直接执行扩展方法Enumerable.Count(…),远比创建一个全新的数组来调用count更为可取. …!