在VB中实现IEnumerable的方法 [英] Ways of implenting IEnumerable in VB

查看:350
本文介绍了在VB中实现IEnumerable的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,我无法理解经典(也许是长篇大论)的做法,多个班级和新收益率路线(显然)是否相同。



我能理解经典路线(我认为),请看下面的代码。

如果我理解,产量会让我感到困惑。它是正确的然后它是绝对的天才,我得到一个状态机的想法(我认为)和逻辑上它有点意义但我完全没有信心。



可能这么简单吗?你只需要根据你的情况做一个简单或复杂的方法吗?

(警告,愚蠢的例子,因为数组已经可以枚举,但很容易演示) < pre lang =vb> 公共 YieldExample
Implements IEnumerable

私有 _Thing 作为 Double ()

公共 Iterator 功能 GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
If IsNothing( Me ._ Thing)然后
抛出 InvalidO perationException()
结束 如果

对于索引作为 整数 = 0 ._ Thing.GetUpperBound( 0
收益率 Me ._ Thing(Index)
Next
结束 功能

结束 班级



我理解为老路。

 公共  ExampleEnumerable 
实现 IEnumerable( of Double )

Private _Thing As Double ()

公共 Function GetEnumerator() as IEnumerator( of Double Implements IEnumerable( of Double )。GetEnumerator
返回 ExampleEnumerator( ._ Thing)
结束 功能

公共 功能 GetEnumerator1() As IEnumerator Implements IEnumerable.GetEnumerator
返回 .GetEnumerator
结束 功能
结束



公共 ExampleEnumerator
实现 IEnumerator( Double

私有 _Thing 正如 Double ()
私有 _Index 作为 整数
私有 _curItem 作为 Double

公共 Sub ByVal 事情作为 Double ())
Me ._ Thing = Thing
Me ._Index = -1
._ curItem = 没什么
< span class =code-keyword>结束 Sub

公开 ReadOnly 属性当前作为 Double Implements IEnumerator( of Double )。当前
获取
如果 IsNothing( Me ._ curItem)然后
抛出 InvalidOperationException()
结束 如果
返回 ._ curItem
结束 获取
结束 财产

公共 ReadOnly 属性 Current1 正如 对象 Implements IEnumerator.Current
获取
返回 .Current
结束 获取
结束 属性

公共 功能 MoveNext() As Boolean Implements IEnumerator。 MoveNext
' 如果我们已经在最后那么返回false
如果 ._ Index = ._ Thing.GetUpperBound ( 0 然后
返回 错误
结束 如果
' 否则移至数组中的下一个位置
Me 。 _Index + = 1
._ curItem = ._ Thing( Me ._ Index)
返回 True
结束 功能

公共 Sub 重置()实施 IEnumerator.Reset
Me ._ Index = -1
Me ._ curItem = < span class =code-keyword> Nothing
结束 Sub

#RegionIDisposable支持

结束



谢谢,

迈克

解决方案

如果有人偶然发现这个,那么我最终回答了自己的问题问题,是产量是编写自己的枚举器的一种非常快捷方便的捷径,在大多数情况下,这可能至少同样有效。如果编写枚举器,编译器只会将yield转换为与它创建的代码非常相似的代码,因此在引擎盖下几乎没有什么区别,除非在特定情况下或者每毫秒计数一次(在这种情况下你可能)无论如何可能都在编写自己的汇编程序。)



选择你的普查员& Me.Understand Yield和IEnumerable(C#) [ ^ ]

选择你的普查员& Me.Understand Yield和IEnumerable(VB) [ ^ ]



Mike


OK, I cannot get my head around the whether there is a difference between the 'classic' (perhaps long winded) way of doing it, multiple classes and the 'new' Yield route to (apparently) the same end.

I can understand the classic route (I think), see the code below.
Yield confuses the heck out of me, if I understand it correctly then it's absolutely genius, I get the idea of a state machine (I think) and logically it sort of makes sense but I am not at all confident.

Can it possibly be this simple? You just make that one method as simple or complex as necessary for your situation?
(Warning, silly example since arrays can already be enumerated, but it's easy to demo)

Public Class YieldExample
    Implements IEnumerable

    Private _Thing As Double()

    Public Iterator Function GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
        If IsNothing(Me._Thing) Then
            Throw New InvalidOperationException()
        End If

        For Index As Integer = 0 To Me._Thing.GetUpperBound(0)
            Yield Me._Thing(Index)
        Next
    End Function

End Class


What I understand to be the 'old way'.

Public Class ExampleEnumerable
    Implements IEnumerable(Of Double)

    Private _Thing As Double()

    Public Function GetEnumerator() As IEnumerator(Of Double) Implements IEnumerable(Of Double).GetEnumerator
        Return New ExampleEnumerator(Me._Thing)
    End Function

    Public Function GetEnumerator1() As IEnumerator Implements IEnumerable.GetEnumerator
        Return Me.GetEnumerator
    End Function
End Class



Public Class ExampleEnumerator
    Implements IEnumerator(Of Double)

    Private _Thing As Double()
    Private _Index As Integer
    Private _curItem As Double

    Public Sub New(ByVal Thing As Double())
        Me._Thing = Thing
        Me._Index = -1
        Me._curItem = Nothing
    End Sub

    Public ReadOnly Property Current As Double Implements IEnumerator(Of Double).Current
        Get
            If IsNothing(Me._curItem) Then
                Throw New InvalidOperationException()
            End If
            Return Me._curItem
        End Get
    End Property

    Public ReadOnly Property Current1 As Object Implements IEnumerator.Current
        Get
            Return Me.Current
        End Get
    End Property

    Public Function MoveNext() As Boolean Implements IEnumerator.MoveNext
        'If we are already at the end then return false
        If Me._Index = Me._Thing.GetUpperBound(0) Then
            Return False
        End If
        'Otherwise move to the next position in the array
        Me._Index += 1
        Me._curItem = Me._Thing(Me._Index)
        Return True
    End Function

    Public Sub Reset() Implements IEnumerator.Reset
        Me._Index = -1
        Me._curItem = Nothing
    End Sub

    #Region "IDisposable Support"
 
End Class


Thanks,
Mike

解决方案

If anyone ever stumbles into this then I ended up answering my own question, yes yield is a very quick and easy shortcut to writing your own enumerator and in the majority of cases is probably at least as effective. The compiler simply turns yield into very similar code to that which it creates if you write the enumerator, so 'under the hood' there is very little difference, except possibly in specific cases or when every millisecond counts perhaps (in which case you'd probably be writing your own assembler anyway).

Pick Your Enumerator & Me.Understand Yield and IEnumerable (C#)[^]
Pick Your Enumerator & Me.Understand Yield and IEnumerable (VB)[^]

Mike


这篇关于在VB中实现IEnumerable的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆