rksoftware

Visual Studio とか C# とかが好きです

C# 9.0 の確認「共変の戻り値の型」

C# 9.0 の確認の目次はこちら

■ 共変の戻り値の型

ドキュメントはこちら

適合性と完成度の機能 という項目の割と読み進めた所の 「共変の戻り値の型を使用すると、」 から始まるブロックです。
ドキュメントにちゃんと書いてはあるのですが、説明が少なすぎて一目で理解しづらいのでコードを書いてみましょう。

■ 検証コードと結果

■ 以前はこれはエラーになる

次のコードは以前の C# ではエラーになりました。

internal class A
{
    public virtual IEnumerable<int> Method() { return null; }
}

internal class B : A
{
    public override List<int> Method() { return new List<int>(); }
}

エラーとなるのはクラス B の Method メソッドの宣言です。
エラーの内容は次のようなものでクラス A とクラス B の Method メソッドの戻り値の型を合わせる必要があると言われます。

'B.Method()': ターゲットのランタイムはオーバーライドで戻り値の型 covariant をサポートしていません。戻り値の型は、オーバーライドされるメンバー 'A.Method()' と一致する 'IEnumerable<int>' にする必要があります

■ C# 9 では

C# 9 ではエラーになりません。エラーにならないということは次のようなコードが書けます。

internal class A
{
    public virtual IEnumerable<int> Method() { return null; }
}

internal class B : A
{
    public override List<int> Method() { return new List<int>(); }
}

internal class C
{
    public void Main()
    {
        A a = new B();
        IEnumerable<int> list = a.Method();
    }
}

a.Method()List<int> を返していますが、その値は IEnumerable<int> 型の変数に代入することが可能です。

IEnumerable<int> list = a.Method();  // return 値 は List<int>

地味ですがこういうことなのでしょう。

■ まとめ

C# が賢くなりました。積極的に狙って書くことがあるかどうかは人次第でしょう。しかしまあ他言語でできることですしできるだけ方は厳格に使っていきたいものです。完全に理解して使いこなしましょう。