It is not possible to use Enumerable.Count with a list; the compiler assumes List.Count

I have not noticed this behavior yet, perhaps because I prefer the query syntax in VB.NET and separate the request and execution methods into different operators.

If I try to compile the following simple query:

Dim wordList As List(Of String) = New List(Of String) Dim longWords As Int32 = wordList.Count(Function(word) word.Length > 100) 

The compiler does not like this because it does not expect arguments for List.Count :

The "Public Readonly Property Count As Integer" has no parameters, and its return type cannot be indexed.

If I declare it as IEnumerable(Of String) , it works as expected:

 Dim wordSeq As IEnumerable(Of String) = New List(Of String) Dim longWords As Int32 = wordSeq.Count(Function(word) word.Length > 100) 

Why is this so? What prevents the compiler from using the Enumerable Count extension method instead of the ICollection.Count property. Notice that I added Imports System.Linq , and Option Strict and Option Infer On . I am using .NET 4.0 (Visual Studio 2010).

I am confused because in C # this works without problems:

 List<String> wordList = new List<String>(); int longWordCount = wordList.Count(word => word.Length > 100); 
+7
c # linq
source share
4 answers

It is by design , quote from MSDN :

The situation is simpler with properties: if the extension method has the same name as the property of the class that it extends, the extension method is not displayed and cannot be accessed.

+5
source share

In C #, only the method of calling a property uses the syntax of the properties (ie) instance.PropertyName , where, as in Vb.Net, there are two options.

 Dim list As List(Of String) = New List(Of String)() Dim count = list.Count() //Method 1 Dim count2 = list.Count //Method 2 

Suppose you add a Count extension method without parameters, what does list.Count() mean? It always gives priority to instance members, so it points to a Property.

Ok, what does list.Count(Function(s) s.StartsWith("a")) mean? In this case, does this mean an extension method?

Then there is no consistency in the language, I think that designers deliberately avoided this function for consistency.

+1
source share

If you pass IEnumerable when you need an extension method, everything will be fine:

 Dim longWords As Int32 = CType(wordList, IEnumerable(Of String)).Count(Function(word) word.Length > 100) 

Or as dcastro is mentioned in a comment:

 Dim longWords As Int32 = wordList.AsEnumerable.Count(Function(word) word.Length > 100) 
+1
source share

One of the main goals of the AsEnumerable method is specifically used when the IEnumerable object type has an element that takes precedence over one of the LINQ extension methods, so you just need to add a call to AsEnumerable before calling Count to remove the member conflict.

+1
source share

All Articles