Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot use Enumerable.Count with List, compiler assumes List.Count

Tags:

c#

.net

vb.net

linq

I haven't noticed this behaviour yet, maybe because i prefer query syntax in VB.NET and split the query and the execution-methods into different statements.

If i try to compile 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 doesn't like this because he expects no arguments for List.Count:

"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 that so? What prevents the compiler from using the Enumerable extension method Count instead of the ICollection.Count property. Note that i've added Imports System.Linq and both Option Strict and Option Infer are On. I'm using.NET 4.0 (Visual Studio 2010).

I'm confused because in C# this works without a problem:

List<String> wordList  = new List<String>();
int longWordCount = wordList.Count(word => word.Length > 100);
like image 397
Tim Schmelter Avatar asked Oct 07 '14 11:10

Tim Schmelter


4 Answers

It's by design, quote from MSDN:

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

like image 73
Adriano Repetti Avatar answered Nov 02 '22 04:11

Adriano Repetti


In C#, only way to call a property is using property syntax (i.e) 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

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

Ok, What does list.Count(Function(s) s.StartsWith("a")) means? In this case it mean the extension method?

There is no consistency in the language then, I guess designers deliberately avoided this feature for consistency.

like image 42
Sriram Sakthivel Avatar answered Nov 02 '22 03:11

Sriram Sakthivel


If you cast to IEnumerable when you need the extension method, everything will be fine:

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

Or as dcastro mentioned in a comment:

Dim longWords As Int32 = wordList.AsEnumerable.Count(Function(word) word.Length > 100)
like image 26
Dave Doknjas Avatar answered Nov 02 '22 04:11

Dave Doknjas


One of the primary purpose of the AsEnumerable method is specifically to be used when the type of an IEnumerable object has a member that takes precedence over one of the LINQ extension methods, so you should simply add in a call to AsEnumerable before calling Count, to remove the member conflict.

like image 29
Servy Avatar answered Nov 02 '22 04:11

Servy