4

私は、「継承されたインスタンス化されたジェネリッククラス」の制限でC#コンパイラを回避する方法を感じてきました。

とにかく、これは私のテストケースです:

class Program
{
    static void Main(string[] args)
    {
        var x = new InClass();
        Console.WriteLine(x.Test(10)); //prints foo
        Console.ReadLine();
    }
}
class BaseClass<Foo, Bar>
{
    public virtual Foo Test(Bar b)
    {
        return default(Foo);
    }
    public virtual string Test(int b)
    {
        return "foo"; ;
    }
}
class InClass : BaseClass<string, int>
{
    /*public override string Test(int b)
    {
        return "bar";
    }*/
}

このInClassの宣言は、あいまいになるため、コンパイラエラーをスローすると思いますTest。また、非ジェネリックTestを内で呼び出すことは不可能になりますInClass。いくつかのコードもコメントアウトされていることに注意してくださいInClass。そのコードのコメントを外すと、コンパイラエラーが発生します。

C#仕様にこの動作についての言及はありますか、それともこれは前代未聞のエッジケースですか?

4

3 に答える 3

7

このInClassの宣言は、Testをあいまいにするため、コンパイラエラーをスローすると思います。

いいえ。仕様では、セクション7.5.3.6でこの種のことを明示的に示しています。

宣言されたシグニチャは一意である必要がありますが、型引数を置き換えると同じシグニチャになる可能性があります。このような場合、上記の過負荷解決のタイブレークルールにより、最も具体的なメンバーが選択されます。

次の例は、このルールに従って有効および無効なオーバーロードを示しています。

(例は明らかに続きます。)

したがって、言語設計者はそれを検討しましたが、おそらく代替案はもっと悪いでしょう。(たとえば、InClass呼び出したくない場合でも、クラスを作成できないのは面倒です。)Test

于 2012-08-23T20:29:20.513 に答える
1

この関連する質問を参照してください:

ジェネリック型の制約が継承可能/階層的に強制されないのはなぜですか

Eric Lippertは、潜在的な影響の徹底的な調査を提供します。

継承されたジェネリック型は、開発チームがそれを下げる価値のないうさぎの穴だと感じたため、コンパイラーによって強制されません。

于 2012-08-23T20:29:25.960 に答える
0

私の推測では、この特定の場合に発生するジェネリック型のメソッドよりも、(int x)シグネチャを使用するメソッドの方が引数によく一致します。intBarint

于 2012-08-23T20:30:41.907 に答える