読者です 読者をやめる 読者になる 読者になる

亀岡的プログラマ日記

京都のベッドタウン、亀岡よりだらだらとお送りいたします。

TPLで楽々セミコロンレスC#

さて、今日も酔ってます(前置き)

TPLはセミコロンレスにうってつけ

セミコロンレスC# を考えた時、難しくなるのはやはり戻り値がvoidのメソッドをどうセミコロンレス = 返り値をもたせるか、ということになります。

つまり、

  1. voidな任意の関数をラップできて
  2. かつラップ後には返り値を作成できること

が要件になります。

んでですね、、、TPLは、ほとんどのAction / Func デリゲートをラップでき、かつ返り値にはTaskかTask<T>型を返すんですよね!

てなわけで、基本方針。

  1. あらゆるメソッドTask,Factory.StartNew で生成し、Task型を受ける。
  2. ContinueWithで追加の処理を足していく

んで、意外と軽く実装できまして

static void Main(string[] args)
{
    if(System.Threading.Tasks.Task.Factory.StartNew(() => 0)
        .ContinueWith(task => System.Console.WriteLine("Hello Semicolonless World!!"))
        .ContinueWith(task => System.Console.WriteLine("And we can do anything!!")) 
        == null)
 }

そう、これで何でもできるのですよ。はい。
変数もTaskの戻り値としてContextに足していきゃあ済むわけで。

んじゃ、恒例のFizzBuzzを。

static void Main(string[] args)
{
    if (System.Threading.Tasks.Task.Factory.StartNew(() => System.Linq.Enumerable.Range(1,100))
        .ContinueWith(task => System.Linq.Enumerable.Select(task.Result, i => i % 15 == 0 ? "FizzBuzz": i % 3 == 0 ? "Fizz" : i % 5 == 0 ? "Buzz" : i.ToString()))
        .ContinueWith(task => System.Linq.Enumerable.ToList( task.Result).ForEach(System.Console.WriteLine))
        == null)
    { }

    if (System.Console.Read() == null) { }
}