【C#】【VB.NET】StreamReaderでスキップして1行先を読み込む方法

CSVを読み込むときに、ループの現在行を変えずに次の行をカンニングしたいケースがあります。
StreamReaderはランダムアクセスできないものですが、継承クラスを利用することで可能だったのでメモします。
この力、マリアンヌ様以外に使うことがあろうとはな!!

参考サイト
stackoverflow.com

C#の場合

using System.IO;

public class PositionableStreamReader : StreamReader
{
    public PositionableStreamReader(string path)
        : base(path)
    { }

    private int myLineEndingCharacterLength = Environment.NewLine.Length;
    public int LineEndingCharacterLength
    {
        get { return myLineEndingCharacterLength; }
        set { myLineEndingCharacterLength = value; }
    }

    public override string ReadLine()
    {
        string line = base.ReadLine();
        if (null != line)
            myStreamPosition += base.CurrentEncoding.GetByteCount(line) + myLineEndingCharacterLength;
        return line;
    }

    private long myStreamPosition = 0;
    public long Position
    {
        get { return myStreamPosition; }
        set
        {
            myStreamPosition = value;
            this.BaseStream.Position = value;
            this.DiscardBufferedData();
        }
    }
}

/// <summary>
/// 使用例
/// </summary>
private static void ReadFile(string file)
{
    using (PositionableStreamReader positionableStreamReader = new PositionableStreamReader(file))
    {
        while (positionableStreamReader.Peek() >= 0)
        {
            // 1行読み込みする
            string readLine = positionableStreamReader.ReadLine();
            string[] split = readLine.Split(',');

            // 処理・・・

            // 1行先をカンニングする
            if (positionableStreamReader.Peek() < 0)
            {
                // 最終行まで到達した
            }
            else
            {
                // ストリームの現在位置を記録する
                long position = positionableStreamReader.Position;

                // 1行先を取得する
                string nextLine = positionableStreamReader.ReadLine();

                // ストリームの現在位置を戻す
                positionableStreamReader.Position = position;

                // 処理・・・

            }
        }
    }
}

VB.NETの場合

Imports System.IO

Class PositionableStreamReader
    Inherits StreamReader

    Sub New(path As String)
        MyBase.New(path)
    End Sub

    Private myLineEndingCharacterLength As Integer = Environment.NewLine.Length
    Public Property LineEndingCharacterLength() As Integer
        Get
            Return myLineEndingCharacterLength
        End Get
        Set(ByVal value As Integer)
            myLineEndingCharacterLength = value
        End Set
    End Property

    Public Overrides Function ReadLine() As String
        Dim line As String = MyBase.ReadLine()
        If line IsNot Nothing Then
            myStreamPosition += MyBase.CurrentEncoding.GetByteCount(line) + myLineEndingCharacterLength
        End If
        Return line
    End Function

    Private myStreamPosition As Long = 0
    Public Property Position() As Long
        Get
            Return myStreamPosition
        End Get
        Set(ByVal value As Long)
            myStreamPosition = value
            MyBase.BaseStream.Position = value
            MyBase.DiscardBufferedData()
        End Set
    End Property
End Class

''' <summary>
''' 使用例
''' </summary>
Private Sub ReadFile(file As String)
    Using positionableStreamReader As New PositionableStreamReader(file)
        While (positionableStreamReader.Peek() >= 0)
            ' 1行読み込みする
            Dim readLine As String = positionableStreamReader.ReadLine()
            Dim split As String() = readLine.Split(","c)

            ' 処理・・・

            ' 1行先をカンニングする
            If (positionableStreamReader.Peek() < 0) Then
                ' 最終行まで到達した
            Else
                ' ストリームの現在位置を記録する
                Dim position As Long = positionableStreamReader.Position

                ' 1行先を取得する
                Dim nextLine As String = positionableStreamReader.ReadLine()

                ' ストリームの現在位置を戻す
                positionableStreamReader.Position = position

                ' 処理・・・

            End If
        End While
    End Using
End Sub