ページ

2011年4月20日水曜日

◆型推論

  static Z F<X, Y, Z>(X value, Func<X, Y> f1, Func<Y, Z> f2)
  {
    return f2(f1(value));
  }


ちょっと前までなら、これを見て「多分これはC#ではない」と思った可能性大である。
Zって何?Fって何?Funcって何?っと?だらけである。

stati int hogeGet(string value , hogeMethod f1 , pekeMethod f2)なんて書いてあればなんてことはないのだが、intがZに変わっただけで全く違った印象になってしまうものだ。
なれれば便利であろう型推論も慣れないと「なんだこれは」となってしまう。

まぁ、これは今に始まったことではなく、クラス名に続くコロンもわかっている人にとっては「継承、もしくは実装」と簡潔に理解できるがそうでない人にとっては、このコロンて何よ?となってしまうだろう。
(ちなみにコボラーな私は最初にC系の言語を見たときにvoidって何?とずっと思っていた)
これが、VBなんかだと若干緩和されていて継承はinherit、実装はimplementといったキーワードが使われるので普通の人は想像がつく。
良くも悪くもC#は簡潔な言語である。

話は戻って、上記のメソッドは第2回 ラムダ式と型推論 - @ITにてこんなサンプルとして載っていた。

using System;
class Program
{
  static Z F<X, Y, Z>(X value, Func<X, Y> f1, Func<Y, Z> f2)
  {
    return f2(f1(value));
  }
  static void Main(string[] args)
  {
    double seconds = F("1:15:30",
                       s => TimeSpan.Parse(s),
                       t => t.TotalSeconds);
    Console.WriteLine(seconds);
  }
}

使い方を見て、やっと
static double F<string,TimeSpan,double>~
って事かと判る。
すなわち、型推論の前にジェネリックに今ひとつついていけていないのだ。
このFメソッドの定義を見て「おー、これは便利なメソッドだ」といってその下のサンプルのような実装を私が書くことは無いように思う。(笑)

話を推論型に戻すと、上記サンプルは本来型指定を行えば、

class Program
{
    static Z F<X, Y, Z>(X value, Func<X, Y> f1, Func<Y, Z> f2)
    {
        return f2(f1(value));
    }
    static void Main(string[] args)
    {
        double seconds = F<string,TimeSpan,double>("1:15:30",
                           (string s) => TimeSpan.Parse(s),
                           (TimeSpan t) => t.TotalSeconds);
        Console.WriteLine(seconds);
    }
}

てな感じになるのだろうか。
慣れないとこの方が判り易いと思うが、慣れてくると冗長でタコなコーディングと批判されるのだろう。

COBOLの時代でも、あまりに頭のよい人が書いたソースはどうも判りづらいと思ったものがだが、最近のC#はよりソースの質の差が出やすくなってきているように思う。

自分一人で作って、自分一人がメンテナンスするのであれば何も問題は無いのだが、大プロジェクトになってくるとその基準を決めるのが難しい。
特に最近のプロジェクトでは作る人と保守する人が違うのは当たり前になってきているので余計考えさせられる。

COBOLの時代は良かったなぁ。(笑)

0 件のコメント:

コメントを投稿

私が最近チェックした記事