本文介绍了每个循环的VB.Net是怎样看待推断类型的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在以下代码中,

 对于MyCollection中的每个项目
...
下一个

编译器用于确定项目

<$ p



$ p $ 公共类BaseDataObjectGenericCollection(Of T)
继承BaseDataObjectCollection
结束类

每个循环的A依然推断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 
返回MyBase.Cast(Of T)()。GetEnumerator
End Function



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

  Public Shadows Function GetEnumerator()As System.Collections.Generic.IEnumerator (T)实现System.Collections.Generic.IEnumerable(Of T).GetEnumerator 
返回MyBase.Cast(Of T)()。GetEnumerator
End Function

这可以起作用,for循环获得正确的类型推断。所以我想现在的问题是, For Each 只需寻找一个名为 GetEnumerator

的函数

解决方案

好吧,只有一个地方可以解决这个问题。规范!



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

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

 选项推断
$ b公共模块M
Sub Main()
For Each x In New SomeClass()

Next
End Sub
End Module

Public Class SomeClass
Public Function GetEnumerator()作为MyEnumerator
返回新的MyEnumerator()
结束函数
结束类


公共类MyEnumerator
公共ReadOnly属性当前As整数
获取
返回42
结束获取
结束属性

公共函数MoveNext()作为布尔
返回True
End函数
结束类

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


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 a Current property. 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:

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

The type of "x" in the Sub Main() is Integer, since the Current property returns Integer.

这篇关于每个循环的VB.Net是怎样看待推断类型的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-15 06:16