在vb.net中绕过收益率的问题

时间:2016-05-19 19:06:51

标签: .net vb.net

(整个代码块位于页面底部)

首先让我先了解一下,我知道在VB 2015中有收益(从我看到的)。但是我的工作迫使我从2010年开始编码。所以......我必须找到一个解决方法。我的代码使用Jon Skeet回答如何读取文件"自下而上" (在c#中):How to read a text file reversely with iterator in C#

代码工作正常 - 除非收益率。因此,我将字符串添加到字符串List中,而不是"产生",

   If firstYield AndAlso String.IsNullOrEmpty(previousEnd) Then

                Return results
            End If
            If (previousEnd IsNot Nothing) Then
               'yield was here
                results.Add(previousEnd)


            Else
                results.Add("")
                'yield was here
                Return results
            End If

            Return results
       Finally
            For i As Integer = 0 To results.Count - 1
                Console.WriteLine(results(i))
            Next

            stream.Dispose()

运行此代码我收到此错误:  无法转换类型&System; System.Collections.Generic.List`1 [System.String]'输入' System.Collections.Generic.IEnumerator' 1 [System.String]

现在,我确实理解我试图将一个String列表返回给一个假定返回Type字符串枚举器的方法。但我迷失了如何使我的代码工作,我试图做一个返回数组,如:

results.ToArray()

这不起作用,因为我的初始方法无法在其实现时返回一个数组: Implements System.Collections.Generic.IEnumerable(Of String).GetEnumerator 当我尝试时VS和VS给我带来了各种各样的错误(也许我写错了语法,我对VB很新)。 但是,当我只使用console.Writeline时,我的整个文件在我的结果列表中正确复制。所以我唯一的问题是正确返回字符串列表。

这里有两种方法(非常冗长,因此我之前解释过我的问题):

   Private Function GetEnumeratorImpl(stream As Stream) As IEnumerator(Of String)
        Dim results As New List(Of String)
        Try
            Dim position As Long = stream.Length

            If TypeOf encoding Is UnicodeEncoding AndAlso (position And 1) <> 0 Then
                Throw New InvalidDataException("UTF-16 encoding provided, but stream has odd length.")
            End If

            ' Allow up to two bytes for data from the start of the previous
            ' read which didn't quite make it as full characters
            Dim buffer__1 As Byte() = New Byte(bufferSize + 1) {}
            Dim charBuffer As Char() = New Char(encoding.GetMaxCharCount(buffer__1.Length) - 1) {}
            Dim leftOverData As Integer = 0
            Dim previousEnd As [String] = Nothing
            ' TextReader doesn't return an empty string if there's line break at the end
            ' of the data. Therefore we don't return an empty string if it's our *first*
            ' return.
            Dim firstYield As Boolean = True

            ' A line-feed at the start of the previous buffer means we need to swallow
            ' the carriage-return at the end of this buffer - hence this needs declaring
            ' way up here!
            Dim swallowCarriageReturn As Boolean = False

            While position > 0
                Dim bytesToRead As Integer = Math.Min(If(position > Integer.MaxValue, bufferSize, CInt(position)), bufferSize)

                position -= bytesToRead
                stream.Position = position
                StreamUtil.ReadExactly(stream, buffer__1, bytesToRead)
                ' If we haven't read a full buffer, but we had bytes left
                ' over from before, copy them to the end of the buffer
                If leftOverData > 0 AndAlso bytesToRead <> bufferSize Then
                    ' Buffer.BlockCopy doesn't document its behaviour with respect
                    ' to overlapping data: we *might* just have read 7 bytes instead of
                    ' 8, and have two bytes to copy...
                    Array.Copy(buffer__1, bufferSize, buffer__1, bytesToRead, leftOverData)
                End If
                ' We've now *effectively* read this much data.
                bytesToRead += leftOverData

                Dim firstCharPosition As Integer = 0
                While Not characterStartDetector(position + firstCharPosition, buffer__1(firstCharPosition))
                    firstCharPosition += 1
                    ' Bad UTF-8 sequences could trigger this. For UTF-8 we should always
                    ' see a valid character start in every 3 bytes, and if this is the start of the file
                    ' so we've done a short read, we should have the character start
                    ' somewhere in the usable buffer.
                    If firstCharPosition = 3 OrElse firstCharPosition = bytesToRead Then
                        Throw New InvalidDataException("Invalid UTF-8 data")
                    End If
                End While
                leftOverData = firstCharPosition

                Dim charsRead As Integer = encoding.GetChars(buffer__1, firstCharPosition, bytesToRead - firstCharPosition, charBuffer, 0)
                Dim endExclusive As Integer = charsRead

                For i As Integer = charsRead - 1 To 0 Step -1
                    Dim lookingAt As Char = charBuffer(i)
                    If swallowCarriageReturn Then
                        swallowCarriageReturn = False
                        If lookingAt = ControlChars.Cr Then
                            endExclusive -= 1
                            Continue For
                        End If
                    End If
                    ' Anything non-line-breaking, just keep looking backwards
                    If lookingAt <> ControlChars.Lf AndAlso lookingAt <> ControlChars.Cr Then
                        Continue For
                    End If
                    ' End of CRLF? Swallow the preceding CR
                    If lookingAt = ControlChars.Lf Then
                        swallowCarriageReturn = True
                    End If
                    Dim start As Integer = i + 1
                    Dim bufferContents As New String(charBuffer, start, endExclusive - start)
                    endExclusive = i
                    Dim stringToYield As String = If(previousEnd Is Nothing, bufferContents, bufferContents & previousEnd)
                    If Not firstYield OrElse stringToYield.Length <> 0 Then
                        results.Add(stringToYield)
                    End If
                    firstYield = False
                    previousEnd = Nothing
                Next

                previousEnd = If(endExclusive = 0, Nothing, (New String(charBuffer, 0, endExclusive) & previousEnd))

                ' If we didn't decode the start of the array, put it at the end for next time
                If leftOverData <> 0 Then
                    Buffer.BlockCopy(buffer__1, 0, buffer__1, bufferSize, leftOverData)
                End If
            End While
            If leftOverData <> 0 Then
                ' At the start of the final buffer, we had the end of another character.
                Throw New InvalidDataException("Invalid UTF-8 data at start of stream")
            End If
            If firstYield AndAlso String.IsNullOrEmpty(previousEnd) Then

                Return results
            End If
            If (previousEnd IsNot Nothing) Then
                results.Add(previousEnd)


            Else
                results.Add("")
                Return results
            End If

            Return results

        Finally
            For i As Integer = 0 To results.Count - 1
                Console.WriteLine(results(i))
            Next

            stream.Dispose()

        End Try

    End Function

    Private Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
        Return GetEnumerator()
    End Function

    Public Function GetEnumerator() As System.Collections.Generic.IEnumerator(Of String) Implements System.Collections.Generic.IEnumerable(Of String).GetEnumerator
        Dim stream As Stream = streamSource()

        If Not stream.CanSeek Then
            stream.Dispose()
            Throw New NotSupportedException("Unable to seek within stream")
        End If

        If Not stream.CanRead Then

            stream.Dispose()
            Throw New NotSupportedException("Unable to read within stream")

        End If
        Return GetEnumeratorImpl(stream)
    End Function

1 个答案:

答案 0 :(得分:1)

那么,根据您提供的错误和引用链接,您只需要返回枚举数而不是列表本身。为此,您需要更改

Else
    results.Add("")
    'yield was here
    Return results
End If

代表

Else
    results.Add("")
    'yield was here
    Return results.GetEnumerator()
End If

您的函数返回确实需要ienumerator而不是列表,因此您会收到此错误。