ページ

2005年2月18日金曜日

Generic な型どうしの互換性

Generic type parameter variance in the CLR より。


うーんと、、、、


string[] ary_s と object[] ary_o があった場合、ary_o = ary_s は許されてる。これは string が object の派生クラスだから。しかし、List<strring> list_s と List<object> list_o があった場合、list_o = list_s は C# ではエラーになる。これは、List<string> と List<object> は違う型とみなされるため。
しかし、CLR が禁止しているわけじゃない。Eiffel の generics は常に covariant。ECMA の CLI v2 draft にも covariant、contravariant な generic parameter をサポートするとちゃんと書いてある。
で、IL の記法と同じように C# にも List<+T> なんていう構文を追加するのはどう?
'+' のときは covariant 向きの代入 (Hoge<親> = Hoge<子>) を許し、'-' のときは contravariant 向きの代入 (Hoge<子> = Hoge<親>) の代入を許すって具合。


なんてことが書いてあるみたい。(いくらなんでも要約しすぎか?w まぁ、正直、ちゃんと読めてるか自信ないし、ちゃんと原文を見てもらったほうがよろしいかと)


上記ででてくる ECMA の CLI v2 draft ですが、ちょっと見てみたところ 「Partition1 Architecture」 の 「8.7 Assignment compatibility」 に代入時の Generics の type parameter の互換性について書いてあるみたいです。


で、上記の内容についてですが、、、
個人的には 「どうなんだろ?」 という感じです。C++ の template もこういうことはできないですし。これができるとうれしいときってどれくらいあるんだろ?あんまりピンときません。
ただ、covariant と言うと、Java Generics で covariant return type が許されるようになったというのがあるけど、そういやこれは .NET Generics ではどうなんでしたっけ?
covariant return type っていうのは


    class SuperClass {
virtual SuperClass Clone() { ... }
}
class SubClass : SuperClass {
override SubClass Clone() { ... }
}


こんなやつです(だったと思う)。これはやりたいときが結構あるんですが。(C++ でも最近はできるようになってたはず)


あと、上記の blog を書いてるのは CLR の中の人みたいです。なので、C# コンパイラチームの人が新仕様について語っているというわけじゃありません。

2 件のコメント:

  1. 共変の戻り値型とかいうヤツですね。

    VC7.1から対応しています。

    返信削除
  2. おぉ、ごぶさたしてます>daigoh さん


    そか、やっぱりこの辺は TOP3 リクエストだったりするんですね。

    C# 3.0 かぁ。C# がどういう方向に進化していくのかちょっと楽しみ。

    返信削除