我收到一个Stream,需要将IEnumerable传递给另一个方法.
public static void streamPairSwitchCipher(Stream someStream)
{
...
someStreamAsIEnumerable = ...
IEnumerable returned = anotherMethodWhichWantsAnIEnumerable(someStreamAsIEnumerable);
...
}
Run Code Online (Sandbox Code Playgroud)
一种方法是读取整个Stream,将其转换为字节数组并将其传入,因为Array实现了IEnumerable.但是,如果我能以这样的方式传入它,以至于在传入之前我不必读取整个Stream,那就更好了.
public static IEnumerable<T> anotherMethodWhichWantsAnIEnumerable<T>(IEnumerable<T> p) {
... // Something uninteresting
}
Run Code Online (Sandbox Code Playgroud)
Phi*_*ier 14
这个按字节"按需"逐字节读取你的流:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
或者甚至更短,如果流为空,则不会引发异常,但不会产生任何结果:
public static IEnumerable<byte> streamAsIEnumerable(Stream stream)
{
if (stream != null)
for (int i = stream.ReadByte(); i != -1; i = stream.ReadByte())
yield return (byte)i;
}
Run Code Online (Sandbox Code Playgroud)
我做了一些实验并写了类似于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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
这里的区别在于我将Bytes和Chars添加到Stream作为扩展方法,这让我可以这样编写:
foreach (char c in Console.In.Chars()) { /* ... */ }
Run Code Online (Sandbox Code Playgroud)
为了咧嘴笑,我编写了一个名为TokenizingStateMachine的抽象类,它在TextReader上使用IEnumerable来实现IEnumerable,这样一个简单的解析器可以做类似的事情:
foreach (Token t in stateMachine) {
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5040 次 |
| 最近记录: |