(整个代码块位于页面底部)
首先让我先了解一下,我知道在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
答案 0 :(得分:1)
那么,根据您提供的错误和引用链接,您只需要返回枚举数而不是列表本身。为此,您需要更改
Else
results.Add("")
'yield was here
Return results
End If
代表
Else
results.Add("")
'yield was here
Return results.GetEnumerator()
End If
您的函数返回确实需要ienumerator而不是列表,因此您会收到此错误。