Skip to content
ahzf edited this page Feb 23, 2011 · 8 revisions

A Pipe<S, E> is a C# interface that extends both the IEnumerable<E> and IEnumerator<E> interface. A Pipe<S, E> takes an IEnumerator or IEnumerable yielding objects of type S as input and produces/emits objects of type E. The character S stands for the “source/start” data type and the character E stands for the “emitted” data type.

Here is a simple example demonstrating a single pipe that capitalizes the characters of the strings that come into it.

IPipe<String, String> _CapsPipe = new CapitalizePipe();
_CapsPipe.SetSourceCollection(new List<String>() { "this", "is", "the", "end." });
while(_CapsPipe.MoveNext()) {
    Console.WriteLine(_CapsPipe.Current + " ");
}

This pipe will produce the following output.

THIS IS THE END.

Given that IPipe<S, E> extends IEnumerator<E> and IEnumerable<E>, its possible to string together pipes to create a processing line.

IPipe<String, String>  _CapsPipe  = new CapitalizePipe();
IPipe<String, Integer> _CountPipe = new CountPipe();
_CapsPipe.SetSourceCollection(new List<String>() { "this", "is", "the", "end." });
_CountPipe.SetSource(_CapsPipe);
while(_CapsPipe.MoveNext()) {
    Console.WriteLine(_CountPipe.Current + " ");
}

If the CountPipe takes a String and emits the number of characters in that String, then the previous code will yield the following output.

4 2 3 4

Realize that the output of one pipe must be of the same type as the input of the next pipe. Given that IPipe<S, E> extends IEnumerator<E>, The E of the first pipe becomes the S of the second pipe. In order to make it easier to create chains of pipes, there is a handy Pipeline<S, E> class. This class implements IPipe<S, E> and thus, Pipeline<S, E> objects can be combined like any other pipe (i.e. you can create pipelines of pipelines). But be aware that the pipeline can onlys check the plausibility of the given pipes concatenation at runtime! Here is an example using a Pipeline<S, E> object.

IPipe<String, String>    _CapsPipe  = new CapitalizePipe();
IPipe<String, Integer>   _CountPipe = new CountPipe();
IPipe<Integer, String>   _WordPipe  = new WordPipe();
Pipeline<String, String> _Pipeline  = new Pipeline<String,String>(_CapsPipe, _CountPipe, _WordPipe);
_Pipeline.SetSourceCollection(new List<String>() { "this", "is", "the", "end." });
while(_Pipeline.MoveNext()) {
    Console.WriteLine(_Pipeline.Current + " ");
}

Assuming that WordPipe emits the word version of an incoming integer, the pipeline will produce the following output.

four two three four

back Creating a Pipe