I was helping someone on StackOverFlow.com and ran into an interesting issue. The post is here.
I explained the issue in my response, but I’ll try to sum up. Newer collection types implement IEnumerable(Of T) as opposed to the original IEnumerable interface. For example, System.Generic.List(Of T) implements IEnumerable(Of T), so the following is valid without casting:
Dim names As New Generic.List(Of String)
names.Add("Bob")
names.Add("Bill")
names.Add("Joe")
names.Add("Zeke")
Dim threeLetterNames = From name In names _
Where name.Length = 3 _
Select name
Dim i As Integer = 1
For Each name As String In threeLetterNames.ToList()
Console.WriteLine("Name {0} of {1}: {2}", i, threeLetterNames.Count, name)
i += 1
Next
Console.Read()
Because the Generic List returns strings. So “name” in the Where clause is a string.
In the original poster’s question, they were using a DataGridViewRowCollection. It implements IEnumerable. So any Linq code sees each item as an object.
Here’s what’s strange about this. The “as type” clause does not resolve the issue. In a for each loop, it does resolve it. Why does For Each compile to include a cast, and Linq does not? That’s a good question for Microsoft.