Acabo de lanzar esto juntos, por lo que no es súper robusto (sin manejo de errores, etc.) pero el caso de prueba básico funciona.
Funciona mediante la creación de un método de extensión para TextReader
's que tienen un segundo, y devuelve una nueva clase TextReader el que llama internamente Read()
en la primera hasta que se agote, y luego comienza a llamar Read()
en el segundo. Puedes encadenar esto indefinidamente.
Para proporcionar una implementación completa de TextReader
sólo tiene que poner en práctica Read()
, Peek()
, Close()
y Dispose()
. Todos los demás métodos se basan en la implementación específica Read()
para funcionar. Por lo tanto, crear tu propio TextReader
realmente no es tan malo, como puedes ver a continuación.
Esto también alivia cualquier problema de rendimiento ya que simplemente estamos envolviendo los TextReaders existentes y no los invocamos para realizar la concatenación.
class Program
{
static void Main(string[] args)
{
StringReader first = new StringReader("hello ");
StringReader second = new StringReader("world");
StringReader third = new StringReader("!");
using (var allOfThem = first.Concat(second).Concat(third))
{
//writes "hello world!"
Console.WriteLine(allOfThem.ReadToEnd());
}
Console.Read();
}
}
public static class Extensions
{
public static TextReader Concat(this TextReader first, TextReader second)
{
return new ChainedTextReader(first, second);
}
private class ChainedTextReader : TextReader
{
private TextReader first;
private TextReader second;
private bool readFirst = true;
public ChainedTextReader(TextReader first, TextReader second)
{
this.first = first;
this.second = second;
}
public override int Peek()
{
if (readFirst)
{
return first.Peek();
}
else
{
return second.Peek();
}
}
public override int Read()
{
if (readFirst)
{
int value = first.Read();
if (value == -1)
{
readFirst = false;
}
else
{
return value;
}
}
return second.Read();
}
public override void Close()
{
first.Close();
second.Close();
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
first.Dispose();
second.Dispose();
}
}
}
}
Oh, eso es inteligente: solo manipule 2, y use un método de extensión para encadenarlos. – Ken