2012-03-18 38 views
1

使用C#/ .Net 4.0的标准功能可以使用enumerable读取控制台中的输入吗?我不认为它有任何实际用法,更像锻炼。将控制台输入读为enumerable - 一条语句?

这就是我很快提出作为一个关于“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

这是个好问题 – 2017-03-07 07:59:57

回答

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); 
} 
+0

+1。好的方法,如果实际上需要做到这一点。但我仍然对一个适合于一个声明的人感兴趣。 – 2012-03-18 08:15:29

+0

这将是困难的:为了使用LINQ,你必须有一个集合。这就是您使用Enumerable.Repeat(0,int.MaxValue)的原因。 – schglurps 2012-03-18 08:34:25

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公开InOutTextReaderTextWriter您可以简单地获取所有使用Console.In.AsEnumerable()的行将它包含在t他LINQ查询。相同的扩展方法适用于任何TextReader

+0

谢谢。从实践的角度来看,你和schglurps的答案是有用的。被接受的schglurps'就像他之前所做的一样,似乎没有更短的“一个声明”的答案,因为在Reader中没有构建迭代器。 – 2012-03-19 16:34:12

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); 
+2

你可以'while(true){}' – abatishchev 2014-03-26 02:07:16

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#功能的单线程:)