.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!
'new' Print()の場合、そのメソッドはPrintMeインターフェイスの一部ではありません。
あなたは同じ結果を得るでしょう
((PrintMe)new Bar()).Print();
ジェネリックはまったくありません。
これはCLRが何をするかという問題ではなく、言語が何をするかという問題です。 C#仕様によると:
クラスは、その基本クラスによって提供されるすべてのインターフェース実装を継承します。
インターフェイスを明示的に再実装しない限り、派生クラスは、基本クラスから継承するインターフェイスマッピングを変更することはできません。
仕様は、上記のものとほぼ同じ例を提供します。
これは、希望どおりに動作させるには、インターフェイスを再実装する必要があることも意味します。
c#
class Bar : Foo, PrintMe
{
public new void Print()
{
Console.WriteLine("Bar!");
}
}
@svick答えてくれてありがとう
最も参考になるコメント
'new' Print()の場合、そのメソッドはPrintMeインターフェイスの一部ではありません。
あなたは同じ結果を得るでしょう
ジェネリックはまったくありません。