2010-04-13 14 views
11

Recibo un Stream y necesito pasar un IEnumerable a otro método.Convertir flujo en IEnumerable. Si es posible al "mantener la pereza"

public static void streamPairSwitchCipher(Stream someStream) 
{ 
    ... 
    someStreamAsIEnumerable = ... 
    IEnumerable returned = anotherMethodWhichWantsAnIEnumerable(someStreamAsIEnumerable); 
    ... 
} 

Una forma es leer toda la corriente, convertirlo en una matriz de bytes y pasarlo en, como matriz implementa IEnumerable. Pero sería mucho mejor si pudiera pasar en ella de tal manera que yo no tengo que leer toda la corriente antes de pasarlo en.

public static IEnumerable<T> anotherMethodWhichWantsAnIEnumerable<T>(IEnumerable<T> p) { 
    ... // Something uninteresting 
} 
+0

¿Qué se espera para enumerar? ¿Está * realmente * queriendo enumerar cada byte de la secuencia? –

+0

Puede crear un contenedor, envolviendo el flujo, proporcionando el soporte de IEnumerable, implementado de la forma que desee. –

+0

@Jon Skeet: planeo enumerar los bytes de un archivo y dejar que 'anotherMethodWhichWantsAnIEnumerable' que ya está implementado haga su magia. – Deleted

Respuesta

11

Esto se lee el byte a byte stream 'en la demanda ':

public static IEnumerable<byte> streamAsIEnumerable(Stream stream) 
{ 
    if (stream == null) 
     throw new ArgumentNullException("stream"); 

    for (; ;) 
    { 
     int readbyte = stream.ReadByte(); 
     if (readbyte == -1) 
      yield break; 
     yield return (byte)readbyte; 
    } 
} 

O incluso más corto, y no lanzar una excepción si el flujo es nulo, pero sólo cediendo nada:

public static IEnumerable<byte> streamAsIEnumerable(Stream stream) 
{ 
    if (stream != null) 
     for (int i = stream.ReadByte(); i != -1; i = stream.ReadByte()) 
      yield return (byte)i; 
} 
+1

Acabo de probarlo y noté lo mismo :) Se corrigió. –

+2

Supongo que quiere un IEnumerable . Si desea algo más (por ejemplo, IEnumerable , IEnumerable que contiene todas las líneas de un TextStream, ...) avíseme. –

4

que hice algunos experimentos en este y escribió algo similar a phild:

public static class ExtensionMethods 
{ 
    public static IEnumerable<byte> Bytes(this Stream stm) 
    { 
     while (true) 
     { 
      int c = stm.ReadByte(); 
      if (c < 0) 
       yield break; 
      yield return (byte)c; 
     } 
    } 

    public static IEnumerable<char> Chars(this TextReader reader) 
    { 
     while (true) 
     { 
      int c = reader.Read(); 
      if (c < 0) 
       yield break; 
      yield return (char)c; 
     } 
    } 
} 

La diferencia aquí es que he añadido Bytes y Caracteres a Stream como un método de extensión, que me permite escribir algo como esto:

foreach (char c in Console.In.Chars()) { /* ... */ } 

Y para las muecas, escribí una clase abstracta llamada TokenizingStateMachine que utiliza IEnumerable en TextReader para implementar IEnumerable de manera que un analizador simple puede hacer algo como:

foreach (Token t in stateMachine) { 
} 
Cuestiones relacionadas