...ing logging 4.0

はてなブログに移行しました。D言語の話とかいろいろ。

共変の戻り値型 (Covariant Return Type) の拡張

集中連載「クラス間依存関係の除去」を書いていて思ったこと.


共変の戻り値型をサポートしているD言語では,次のように;

class A {}
class B : A {}
class Foo
{
    A hoge() { return new A; }
}
class Bar : Foo
{
    B hoge() { return new B; } // override with covariant return type
}

戻り値型が異なる Bar.hoge() で Foo.hoge() をオーバーライドすることが許されています.


「それなら」と思い,次のコードを試してみました.

import std.stdio;
class A     { void say(){writefln("I am A.");} }
class B : A { void say(){writefln("I am B.");} }
void main()
{
    A delegate() dg_traditional
        = delegate A() { return new A; }; // of course, ok
    A delegate() dg_new_cast
        = cast(A delegate()) delegate B() { return new B; }; // ok, but..
    //A delegate() dg_new = delegate B() { return new B; }; // error ;-(
    
    dg_traditional().say(); // I am A.
    dg_new_cast().say();    // I am B.
    //dg_new.say();         // I am B.
}

期待通り, dg_new_cast デリゲートが返すオブジェクトは B のようです.
でも,キャストしないといけないのでは covariant return type の意味がありませんね・・・.
covariant return type の考え方をデリゲートにも拡張できたら嬉しいのですが.
このアイデアはどうなんでしょうか>識者の方