Python의 생성기와 코루틴을 C#으로 표현하면.
요즘 이 책을 재미있게 보고 있습니다. ^^
Programming Insight 파이썬 완벽 가이드
; http://www.yes24.com/24/goods/6694057
그중에서 코루틴에 대한 이야기가 재미있습니다. 언어 간의 비교를 해보면 이해도를 높일 수 있고 서로 간의 장단점도 쉽게 파악이 되지요. ^^ 그래서 C#으로 한번 표현을 해봤습니다.
우선, 파이썬에서 yield를 이용한 구문 중에서 코루틴보다 간단한 생성기(generator)에 대한 예제를 먼저 보겠습니다.
def countdown(n):
    while n > 0:
        yield n
        n -= 1
for i in countdown(5):
    print i
이건 좀 쉽습니다. ^^ C#에서도 역시 yield 키워드를 이용해서 다음과 같이 만들어 볼 수 있습니다.
class Program
{
    static void Main(string[] args)
    {
        Program inst = new Program();
        foreach (var item in inst.CountDown(5))
        {
            Console.WriteLine(item);
        }
    }
    IEnumerable<int> CountDown(int maxValue)
    {
        while (maxValue > 0)
        {
            yield return maxValue --;
        }
    }
}
부수적인 코드들이 들어갈 뿐 구조상으로 보면 파이썬의 표현과 거의 1:1 매핑이 됩니다.
다음으로 파이썬의 코루틴입니다. 
def print_matches(matchtext):
    print "Looking for", matchtext
    while True:
        line = (yield)
        if matchtext in line:
            print line
matcher = print_matches("python")
matcher.next()
matcher.send("Hello World")
matcher.send("python is cool")
matcher.close()
// 출력 결과
Looking for python
python is cool
대강 어떤 식인지 눈에 보이시죠? matcher.send의 인자로 입력된 것이 print_matches 함수의 (yield) 문의 결과로 반환되어 식이 평가되고 있는 것입니다.
요건 C#으로 옮기기에 그다지 멋있게 되지는 않지만, 다음과 같이 가능은 합니다.
class Program
{
    static void Main(string[] args)
    {
        Program inst = new Program();
        inst.print_matches("python");
        inst.send("Hello World");
        inst.send("python is cool");
    }
    string _matchText;
    string _message;
    IEnumerator<int> iter;
    void print_matches(string matchtext)
    {
        Console.WriteLine("Looking for: " + matchtext);
        _matchText = matchtext;
        iter = iterator().GetEnumerator();
        iter.MoveNext();
    }
    public void send(string message)
    {
        _message = message;
        iter.MoveNext();
    }
    IEnumerable<int> iterator()
    {
        yield return 0;
        while (true)
        {
            if (_matchText.IndexOf(_message) == -1)
            {
                yield return 0;
            }
            Console.WriteLine(_message);
            yield return 1;
        }
    }
}
음... 다소 억지스러운가요? ^^ 그나저나... 파이썬이라... 마음에 듭니다. ^^
(
예제 코드는 첨부해 두었습니다.)
[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]