使用C#/ .Net 4.0的标准功能,是否有更短/更好的方式在控制台中读取输入为可枚举?我认为没有任何实际用法,更多的是练习。
这就是我快速提出的关于“read array/filter it”的家庭作业问题的答案。基本上我试着编写File.ReadAllLines的控制台等等。
var completeConsoleInput = Enumerable.Repeat(0, int.MaxValue)
.Select(i => Console.ReadLine())
.TakeWhile(s => s != null);
我特别不喜欢我试图用作“永远”迭代器的Enumerable.Repeat(0, int.MaxValue)
,但我不记得看到其他选项了。
答案 0 :(得分:13)
这是一个解决方案:
public static IEnumerable<string> ReadLines()
{
string line;
while(null != (line = Console.ReadLine()))
yield return line;
}
public static void Main()
{
string input = string.Join(ReadLines(), Environment.NewLine);
}
答案 1 :(得分:9)
You're not the first to try this,借助一个简单的扩展方法(类似于schglurps中的方法),您可以轻松地将其内联到LINQ查询中:
public static class TextReaderExtension
{
public static IEnumerable<string> AsEnumerable(this TextReader reader)
{
string line;
while ((line=reader.ReadLine()) != null)
{
yield return line;
}
}
}
由于Console
将In
和Out
公开为TextReader
和TextWriter
,您只需使用Console.In.AsEnumerable()
获取所有行即可在LINQ查询中。相同的扩展方法适用于任何TextReader
。
答案 2 :(得分:2)
我遇到了同样的问题,但我一直在寻找更通用的解决方案。理想情况下,我想扩展System.Linq.Enumerable类,但由于这是不可能的,我不得不把它放在另一个类中。
实现:
public static class MyEnumerable
{
public static IEnumerable<TResult> Repeat<TResult>(Func<TResult> func)
{
for (;;)
{
yield return func();
}
}
}
用法示例:
var completeConsoleInput = MyEnumerable.Repeat(Console.ReadLine)
.TakeWhile(s=> s != null);
答案 3 :(得分:0)
这个怎么样?
// One line to read them all
var lines = Console.In.ReadToEnd().Split(new[]{Environment.NewLine}, StringSplitOptions.None);
用法:
Console.WriteLine(lines.Length + " lines:");
foreach (var line in lines) Console.WriteLine(line);
在读取所有行之前,你不会得到IEnumerable,类似于File.ReadAllLines;但它是一个使用标准C#功能的单线程:)