Runtime: ジェネリックインターフェイスメソッドが呼び出されていない

作成日 2018年08月10日  ·  3コメント  ·  ソース: dotnet/runtime

.NET 2/3/4 / 4.5 /4.6.1および.NetCore 2.1の動作でテストされたサンプルコードはすべて同じですが、なぜこれがこのように処理されるのですか?

明らかに、 PrintIt<T>の呼び出しは、正しいタイプBar作成していますが、実際には正しいメソッドを呼び出すことはありません。

サンプルコード:

interface PrintMe
{
    void Print();
}

class Foo : PrintMe
{
    public void Print()
    {
        Console.WriteLine("Foo!");
    }
}

class Bar : Foo
{
    public new void Print()
    {
        Console.WriteLine("Bar!");
    }
}

class Program
{
    static void Main(string[] args)
    {
        PrintIt<Foo>();
        PrintIt<Bar>();

        var foo = new Foo();
        var bar = new Bar();

        foo.Print();
        bar.Print();

        Console.ReadKey();
    }

    static void PrintIt<T>() where T : PrintMe, new()
    {
        new T().Print();
    }
}

出力:

Foo!
Foo!
Foo!
Bar!

期待される出力:

Foo!
Bar!
Foo!
Bar!
question tracking-external-issue

最も参考になるコメント

'new' Print()の場合、そのメソッドはPrintMeインターフェイスの一部ではありません。

あなたは同じ結果を得るでしょう

((PrintMe)new Bar()).Print();

ジェネリックはまったくありません。

全てのコメント3件

'new' Print()の場合、そのメソッドはPrintMeインターフェイスの一部ではありません。

あなたは同じ結果を得るでしょう

((PrintMe)new Bar()).Print();

ジェネリックはまったくありません。

これはCLRが何をするかという問題ではなく、言語が何をするかという問題です。 C#仕様によると

クラスは、その基本クラスによって提供されるすべてのインターフェース実装を継承します。

インターフェイスを明示的に再実装しない限り、派生クラスは、基本クラスから継承するインターフェイスマッピングを変更することはできません。

仕様は、上記のものとほぼ同じ例を提供します。

これは、希望どおりに動作させるには、インターフェイスを再実装する必要があることも意味します。

c# class Bar : Foo, PrintMe { public new void Print() { Console.WriteLine("Bar!"); } }

@svick答えてくれてありがとう

このページは役に立ちましたか?
0 / 5 - 0 評価