2016-05-19 14 views
0

VBで(私が見たものから)持つ問題

は、私は収率があり承知していることを巻頭してみましょう(コードの全体の塊は、ページの一番下にあります)しかし、私の仕事は私に2010年からのコード作成を強制します。だから...私は仕事を見つけなければなりません。私のコードは、ファイルを "ボトムアップ"(C#)で読む方法について、John Skeetの答えを使用しています。How to read a text file reversely with iterator in C#

コードは正常です。私はこのエラーを取得し、このコードを実行する

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.Collections.Generic.List '1 [System.String]' 'System.Collections.Generic.IEnumerator'1 [System.String]を入力します。

今、私は文字列のリストをメソッドに戻そうとしていることを理解していますType stringの列挙子を返すとします。私の最初の方法はとして配列を返すことはできませんので動作しません

results.ToArray() 

:しかし、私は私のコードを動作させるために何をすべきかの失われた時だ、私は以下のような配列のリターンを実行しようとしましたそれは実装しています:System.Collections.Generic.IEnumerable(Of String).GetEnumeratorを実装しています。私は試してみると多種のエラーを投げかけています(多分私は文法を間違って書いています。 しかし、私はconsole.Writelineを使用すると、私のファイル全体が結果リストに正しくコピーされます。だから私の唯一の問題は正しく文字列のリストを返しています。 (私は前に私の問題を説明し、なぜそれ故に非常に長く、)

はここで2つの方法です:

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

さて、あなたのエラー、あなたが提供される基準リンクによると、あなたは、単に列挙子を返す代わりにする必要がありますリストそのもの。そのためには、それゆえ、なぜあなたはこのエラーを取得し、IEnumeratorをしていないリストを期待していない

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

あなたの関数の戻り値のため

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

を変更する必要があります。

+0

Mhm、私のリストはどこかに失われているように見えますが、私の初期メソッド呼び出しの定義を返すだけなので、正しい答えと思われます。 (それは間違いなく意味をなさないが、それは「それは何であるか」という用語の定義を戻している)。だから、あなたはこの文脈で正しい答えをくれました!ありがとうございました –

+0

EDIT(私のコメントを編集できませんでした)もう一度ありがとう、私は列挙子を反復する必要があることを忘れました。ハハ –