2012-03-18 40 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#功能的單線程:)