Общие методы не вызывают методы типа 'T'

Предположим, у меня есть два класса:

class a
{
    public void sayGoodbye() { Console.WriteLine("Tschüss"); }
    public virtual void sayHi() { Console.WriteLine("Servus"); }
}

class b : a
{
    new public void sayGoodbye() { Console.WriteLine("Bye"); }
    override public void sayHi() { Console.WriteLine("Hi"); }
}

Если я вызываю общий метод, который требует, чтобы тип «T» был производным от класса «a»:

void call<T>() where T : a

Затем внутри этого метода я вызываю методы для для экземпляра типа «T» вызов метода привязан к типу «a», как если бы экземпляр был приведен как «a»:

call<b>();
...
void call<T>() where T : a
{
    T o = Activator.CreateInstance<T>();
    o.sayHi(); // writes "Hi" (virtual method)
    o.sayGoodbye(); // writes "Tschüss"
}

Используя отражение, я могу получить ожидаемые результаты:

call<b>();
...
void call<T>() where T : a
{
    T o = Activator.CreateInstance<T>();
    // Reflections works fine:
    typeof(T).GetMethod("sayHi").Invoke(o, null); // writes "Hi"
    typeof(T).GetMethod("sayGoodbye").Invoke(o, null); // writes "Bye"
}

Кроме того, используя интерфейс для класса 'a', я получаю ожидаемые результаты:

interface Ia
{
    void sayGoodbye();
    void sayHi();
}
...
class a : Ia // 'a' implements 'Ia'
...
call<b>();
...
void call<T>() where T : Ia
{
    T o = Activator.CreateInstance<T>();
    o.sayHi(); // writes "Hi"
    o.sayGoodbye(); // writes "Bye"
}

Эквивалентный неуниверсальный код также отлично работает:

call();
...
void call()
{
    b o = Activator.CreateInstance<b>();
    o.sayHi(); // writes "Hi"
    o.sayGoodbye(); // writes "Bye"
}

То же самое, если я изменю общее ограничение на 'b':

call<b>();
...
void call<T>() where T : b
{
    T o = Activator.CreateInstance<T>();
    o.sayHi(); // writes "Hi"
    o.sayGoodbye(); // writes "Bye"
}

Кажется, что компилятор генерирует вызовы методов для базового класса, указанного в ограничении, поэтому я думаю, что понимаю, что происходит, но это не то, что я ожидал.Это действительно правильный результат?

5
задан Paul 27 January 2011 в 15:35
поделиться