In the following code,
For Each item in MyCollection
...
Next
What does the compiler use to determine the type of item?
For example let say I have this class, which is inheriting a non generic collection,
Public Class BaseDataObjectGenericCollection(Of T)
Inherits BaseDataObjectCollection
End Class
A for each loop still infers the Item type as Object. How would I have to modify the above class to make the type inference work?
Edit: Per Beatles1692’s answer, Implementing IEnumerator(Of T) kinda works. The base class already has a GetEnumerator function, inherited from CollectionBase, so I my implementation looked like this,
Public Function GetEnumerator1() As System.Collections.Generic.IEnumerator(Of T) Implements System.Collections.Generic.IEnumerable(Of T).GetEnumerator
Return MyBase.Cast(Of T)().GetEnumerator
End Function
However, the for loop still infers the type as object. But, if I change the interface implementation to this,
Public Shadows Function GetEnumerator() As System.Collections.Generic.IEnumerator(Of T) Implements System.Collections.Generic.IEnumerable(Of T).GetEnumerator
Return MyBase.Cast(Of T)().GetEnumerator
End Function
That works, the for loop gets the type inference correct. So I guess the question is now, does For Each just look for a function called GetEnumerator ?
Well, there’s only one place to go for a question like this. The spec!
Section 10.9.3 discusses For Each statements. According to it:
“collection” here seems vague, but it’s precisely defined on the next page. Essentially, the type must have a GetEnumerator() call, and this enumerator must (a) have a
MoveNext()method that returns a boolean type, and (b) have aCurrentproperty. The type of the Current property is the type that will be inferred by the compiler. Note it actually has nothing to do with IEnumerator or IEnumerable…you just have to fit the prescribed pattern. Consider this code:The type of “x” in the Sub Main() is Integer, since the Current property returns Integer.