VB.NET の場合、定義されているプロパティが同じクラスで定義されている(もしくは継承したクラスで定義されている)同名のメソッドを隠してしまうという話を、List(Of T) と Count プロパティを例にとって説明します。
例として以下のコードを考えます。
Dim e As IEnumerable(Of Int32) = Enumerable.Range(1, 10)
' これは OK。拡張メソッド Count を呼び出す
Console.WriteLine(e.Count(Function(n) n >= 5))
Dim x As List(Of Int32) = e.ToList
' ビルドエラー「Public ReadOnly Property Count As Integer' には引
' 数がないため、戻り値の型をインデックス化できません。」になる
Console.WriteLine(x.Count(Function(n) n >= 5))
'明示的に拡張メソッドを呼び出せば OK
Console.WriteLine(Enumerable.Count(x, Function(n) n >= 5))
e は IEnumerable(Of T) 型で Count という名前では拡張メソッドの Count のみを実装しています。(同名のプロティは実装されていません)
なので、e.Count(Function(n) n >= 5) で拡張メソッドの Count を呼び出せています。
一方、x は IEnumerable(Of T) から ToList メソッド を使って作成した List(Of T) 型になります。List(Of T) 型には Count プロパティと Count 拡張メソッド(Enumerable.Count のオーバーロード)の両方が実装されています。
VB.NET の場合、List(Of T) 型に実装されている Count プロパティによって拡張メソッドの Count が隠されてしまい、コンパイラは Count プロパティが呼ばれていると判断して上のソースにコメントしたようなビルドエラーになります。
これは VB.NET のコンパイラの問題で、同名のプロパティとメソッドを区別できないところからきているようです。
そのことを書いた Micosoft の公式文書は見つかりませんでしたが、MSDN フォーラムの記事で、Matt Warren - MSFT さんが、
"VB compiler is matching the lists Count property instead of the Enumerable.Count() extension method and the Count property is blocking the visibility of the extension method's other signature."
Timothy Ng MSFT さんが、
"in VB, properties shadow methods (and thus, extension methods) by name."
と書いた説明で自分的には納得しています。
そのことは List(Of T) と Count プロパティ / メソッドに限った話ではなく、以下のような自作のクラスで定義した同名のプロパティとメソッドでも再現できます。
Module Module1
Sub Main()
Dim sample As SampleClass = New SampleClass()
' SampleClass の Name プロパティが呼ばれる
Console.WriteLine(sample.Name)
' 同じく SampleClass の Name プロパティが呼ばれる。
' VB.NET の ( ) は、C# の [ ] と同様に、配列の要素にアク
' セスするので、sample.Name(1) は "Property called." の
' 2 文字目の 'r' となる。
Console.WriteLine(sample.Name(1))
' 同じく SampleClass の Name プロパティが呼ばれる。
' ( ) は文字列(配列)"Property called." の要素にアクセ
' スする。引数 "abc" は Int32 型に変換できないのでビルド
' エラーになる。
Console.WriteLine(sample.Name("abc"))
End Sub
End Module
Public Class SampleClass
Inherits SampleBaseClass
' Shadows キーワードを付けないと以下の警告が出るが、付けな
' くても結局は shadow される。
' 「property 'Name' は、function 'Name' とベース class
' 'SampleBaseClass' で競合しています。'Shadows' として宣言
' されなければなりません。}
Public ReadOnly Property Name() As String
Get
Return "Property called."
End Get
End Property
End Class
Public Class SampleBaseClass
Public Function Name(ByVal i As Int32) As String
Return "Instanse Method called."
End Function
End Class
Public Module MyExtension
<System.Runtime.CompilerServices.Extension()>
Public Function Name(ByVal x As SampleBaseClass, _
ByVal s As String) As String
Return "Extension Method called."
End Function
End Module
なお、C# の場合はこのような問題なく、以下のコードでいずれも期待した通りの結果 6 を取得できます。
IEnumerable<int> e = Enumerable.Range(1, 10);
Console.WriteLine(e.Count(n => n >= 5));
List<int> x = e.ToList();
Console.WriteLine(x.Count(n => n >= 5));
Console.WriteLine(Enumerable.Count(x, n => n >= 5));