什么VB.Net For Each Loop看什么来推断类型

时间:2012-02-20 23:07:57

标签: vb.net generics foreach type-inference

在以下代码中,

For Each item in MyCollection
...
Next

编译器使用什么来确定item的类型?

例如,假设我有这个继承非泛型集合的类

Public Class BaseDataObjectGenericCollection(Of T)
    Inherits BaseDataObjectCollection
End Class

每个循环的A仍然将Item类型推断为Object。我如何修改上面的类以使类型推断工作?

编辑:Per Beatles1692的回答,实现IEnumerator(Of T)有点起作用。基类已经有GetEnumerator函数,继承自CollectionBase,所以我的实现看起来像这样,

    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

但是,for循环仍然将类型推断为对象。但是,如果我将接口实现更改为此,

    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

这样做,for循环得到类型推断正确。所以我想现在的问题是,For Each只是寻找一个名为GetEnumerator的函数吗?

2 个答案:

答案 0 :(得分:1)

你应该写:

For Each Item As SpecificType In MyCollection
....
Next

然后它会在每个循环中将Item转换为SpecificType,或者你的集合应该已经实现了IEnumerable(Of T)

答案 1 :(得分:1)

嗯,这样的问题只有一个地方可以去。规范!

第10.9.3节讨论For Each语句。根据它:

  

[if]正在使用局部变量类型推断,然后标识符定义一个新的局部变量,其范围是整个For循环,其类型是集合的元素类型(如果枚举器表达式被键入为Object,则为Object)

“集合”在这里看起来很模糊,但它在下一页上精确定义。本质上,类型必须具有GetEnumerator()调用,并且此枚举器必须(a)具有返回布尔类型的MoveNext()方法,并且(b)具有Current属性。 Current属性的类型是编译器将推断的类型。注意它实际上与IEnumerator或IEnumerable无关......你只需要符合规定的模式。请考虑以下代码:

Option Infer On

Public Module M
    Sub Main()
        For Each x In New SomeClass()

        Next
    End Sub
End Module

Public Class SomeClass
    Public Function GetEnumerator() As MyEnumerator
        Return New MyEnumerator()
    End Function
End Class


Public Class MyEnumerator
    Public ReadOnly Property Current As Integer
        Get
            Return 42
        End Get
    End Property

    Public Function MoveNext() As Boolean
        Return True
    End Function
End Class

Sub Main()中的“x”类型是Integer,因为Current属性返回Integer。