在下面的代码中,
For Each item in MyCollection
...
Next
编译器使用什么来确定item
的类型?
例如,假设我有这个类,它继承一个非泛型集合,
Public Class BaseDataObjectGenericCollection(Of T)
Inherits BaseDataObjectCollection
End Class
每个循环仍将 Item 类型推断为 Object
。我必须如何修改上面的类才能使类型推断起作用?
编辑:根据 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 循环仍然将类型推断为对象。但是,如果我将接口(interface)实现更改为这样,
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
的函数?
最佳答案
好吧,对于这样的问题只有一个地方可以去。规范!
第 10.9.3 节讨论了 For Each 语句。据其介绍:
[if] local variable type inference is being used, then the identifier defines a new local variable whose scope is the entire For loop and whose type is the element type of the collection (Object if the enumerator expression is typed as Object).
这里的“集合”看起来很模糊,但下一页有明确的定义。本质上,该类型必须有一个 GetEnumerator() 调用,并且该枚举器必须 (a) 有一个 MoveNext()
返回 bool 类型的方法,并且 (b) 有 Current
属性(property)。 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。
关于vb.net - VB.Net For Each Loop 查看什么来推断类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9369803/