Windows Developer Magazine で επιστημη さんが連載されている「世界はオブジェクトの海に浮かぶ」で、今回は「Generics 雑感」として記事を書かれています。
その中で「C# Generics のココが不満」という節があり、C++ の template と比較されています。
「制約による縛り」という項目が私の考えと違っていたので、少し。
class Printer<T>{
public static void Print(T t){
Console.WriteLine("以下のとおり出力します。");
t.Print();
}
class Greet{
public void Print(){
Console.WriteLine("Hello, world");
}
}
Printer<Greet>.Print(new Greet());
上記は C# のコードですが、C++ ならば、OK の構文。つまり、C++ では、「型 T」 に Print() メソッドが存在しさえすれば問題ないのです。
C# ならば、コンパイル時にエラーになります。「型 T」に Print() メソッドが存在するかどうかが分からないからです。
interface IPrint{
void Print();
}
を用意して、Printer と Greet のそれぞれに適用させてやれば、C# でも OK になります。(適用の仕方は調べてください)
私はこの「縛り」が逆に C# の Generics が C++ の template と比べて利点になると思いました。
C++ ではこの「縛り」がないため、「型 T」に渡してもよい型が、明示的に開発者に伝わりません。(Print() がなければ、コンパイルエラーにはなりますが。)
しかも「型 T」に渡す型が、たまたま 意図と違う Print() メソッドを持っていたら、意図通りに動かないでしょう。(Print() メソッド一つだけなら、ありえないかもしれません。しかしもっと複雑になると発生する可能性が高まります。)
C# の Generics は IPrinter.Print() を持つ事を「型 T」に縛るので、上記2点が解決した、と思います。
どうでしょう。
# 記事中のソースコードは「Windows Developer Magazin 01 月号 『世界はオブジェクトの海に浮かぶ』」からの転載です。
# επιστημη さんからは許可を頂きました。ありがとうございます。