C#:IEnumerable<T>の実装サンプルとして簡易catコマンドを作成してみた

この記事は、IEnumerable<T>の実装を理解を深めるために書いたものです。

TextReaderを列挙可能にする

.NET Frameworkには、File.ReadLinesというメソッドが用意されているのですが、入力がファイルに限定されています。しかし、今回作成する簡易catコマンドは、標準入力もサポートしたいので利用できません。

ということで、IEnumerable<T>を実装したEnumerableTextReaderクラスを作成しました。TextReaderオブジェクトから行を順に列挙するクラスです。

汎用性を持たせるために、テキスト形式のStreamも扱えるようにします。

以下、EnumerableTextReaderクラスのソースコードです。

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;

namespace Cat {
    public class EnumerableTextReader : IEnumerable<string> {
        private TextReader _sr;

        public EnumerableTextReader(TextReader tr) => _sr = tr;

        public EnumerableTextReader(Stream s) => _sr = new StreamReader(s);

        public IEnumerator<string> GetEnumerator() {
            string s;
            while ((s = _sr.ReadLine()) != null) {
                yield return s;
            }
        }

        IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();

    }
}

このクラスは、IEnumerable<T>インターフェースを実装していますので、テキストファイルに対して、LINQの拡張メソッドが利用できるようになります。とは言っても、簡易catコマンドではLINQのメソッドは利用してないですが...

TextReaderを受け取るコンストラクタを用意していますので、Console.Inを渡せば、標準入力からも行単位で入力データを列挙することができます。

簡易catコマンドを実装する

上記のEnumerableTextReaderクラスを使って、簡易catコマンドを書いてみました。

このプログラムは、標準入力からデータを読み込み、標準出力に書きだすだけの簡単なものです。

使い方は以下のような感じ。

C:\>cat < sample.txt > sample2.txt

これで、sample.txtの内容を、sample2.txtに複写することができます。

以下のようなcatコマンド名だけの場合、キーボードから入力した行をそのままコンソール画面に表示します。この場合は、Ctrl+Zで入力を終了させます。

C:\>cat

以下、EnumerableTextReaderクラスを利用した簡易catコマンドのソースコードです。

using System;
using System.Linq;
using System.Collections.Generic;

namespace Cat {
    class Program {
        static void Main() {
            var reader = new EnumerableTextReader(Console.In);
            reader.ForEach(Console.WriteLine);
         }
    }

    public static class EnumerableExtentions {
        public static void ForEach<T>(this IEnumerable<T> source, Action<T> action) {
            foreach (T x in source) {
                action(x);
            }
        }
    }
}

補足

このコード、.NET Core 2.0でも動作確認しています。


この記事は、Gushwell's C# Programming Pageで公開したものを加筆・修正したものです。

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.