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

.NET Generics について一言いいたくなったときに読み直すべき PPT

.NET

とりあえず道路族,みたいな.

class root
{ 
}

class derivedA : root
{
} 

class derivedB : root
{
} 

internal class derived<T> : T
    where T : root
{
}

まぁダイヤモンド継承のようなMixinに使いたいんだけど、このC<T>もだめ。

ああ、愛しのテンプレート様。

.NET Generics に関して,この手の疑問が生まれたら,とりあえず読みなおそうという感じなのが以下の PPT.

この中の,Parametric Polymorphism for Popular Programming Languages (PPT) という PPT ファイルの 12 ページ目に,先日波村さんが言われていた「C# 1.0 のリリース時に動く形の Generics 実装が Microsoft Research から上がってきていた」を裏付ける timeline が載ってます.

その他,.NET Generics に関して言われている,利用者視点の「こーだよね」に対する回答の多くもこの PPT に含まれていました.軽く目を通してみると面白いかもしれません.その意味では 14 ページ目も必見.

58 ページ目と 59 ページ目に理由が書いてあります.

Extension: Parameterize by superclass

Can type-check given sufficient constraints:

class D
{
    virtual void m1() { … }
    virtual void m2() { … }
}

class C<T> : T where T : D
{
    int f;
    override void m2(T x) {
        …x.m1()…
    }
    new virtual void m3() {
        …
    }
}

Extension: Parameterized by superclass (2)

  • Provides a kind of “mixin” facility
  • Unfortunately, implementation isn’t easy
  • We’d like to share rep & code for C<P> and C<Q> for reference types P and Q, but it may be the case that
    • object size of C<P> ≠ size of C<Q>
    • field offset of C<P>.f ≠ offset of C<Q>.f
    • vtable slot of C<P>.m3 ≠ slot of C<Q>.m3
    • => abandon sharing, or do more run-time lookup

つまり,ある種の Mix-In としてこれが便利なのは分かるけど,一方で .NET Generics 実装の特色である JIT コンパイル後のコード共有との折り合いが難しいというお話.
なので,これを許すには,C++ の template のようにコード共有をあきらめるか,コード共有をあきらめずに実行時の動作を複雑にするかどっちか選ぶ必要があると.
以上,今日の道路建設終了.
ちなみに 3 年落ちどころじゃなくて 5 年前の PPT なんですなこれ.