C # & generics - почему метод в базовом классе вызывается вместо нового метода в производном классе?

Если аргумент общего типа (вызывающего класса или вызывающего метода) ограничен с помощьюwhere T : Base новый метод в T == Derived не вызывается, вместо этого вызывается метод в Base.

Почему тип T игнорируется при вызове метода, хотя он должен быть известен до выполнения?

Обновит: НО, когда ограничение использует интерфейс типаwhere T : IBase вызывается метод в базовом классе (а не метод в интерфейсе, что тоже невозможно).
Это означает, что система на самом деле способна определять типы, которые выходят далеко за пределы ограничения типов! Тогда почему он не выходит за рамки ограничения типа в случае ограничения с типом класса?
Означает ли это, что метод в базовом классе, который реализует интерфейс, имеет неявное ключевое слово override для метода?

Тестовый код:

public interface IBase
{
    void Method();
}

public class Base : IBase 
{
    public void Method()
    {

    }
}

public class Derived : Base
{
    public int i = 0;

    public new void Method()
    {
        i++;
    }
}

public class Generic<T>
    where T : Base
{
    public void CallMethod(T obj)
    {
        obj.Method();  //calls Base.Method()
    }

    public void CallMethod2<T2>(T2 obj)
        where T2 : T
    {
        obj.Method();  //calls Base.Method()
    }
}

public class GenericWithInterfaceConstraint<T>
    where T : IBase
{
    public void CallMethod(T obj)
    {
        obj.Method();  //calls Base.Method()
    }

    public void CallMethod2<T2>(T2 obj)
        where T2 : T
    {
        obj.Method();  //calls Base.Method()
    }
}

public class NonGeneric
{
    public void CallMethod(Derived obj)
    {
        obj.Method();  //calls Derived.Method()
    }

    public void CallMethod2<T>(T obj)
        where T : Base
    {
        obj.Method();  //calls Base.Method()
    }

    public void CallMethod3<T>(T obj)
        where T : IBase
    {
        obj.Method();  //calls Base.Method()
    }
}

public class NewMethod
{
    unsafe static void Main(string[] args)
    {
        Generic<Derived> genericObj = new Generic<Derived>();
        GenericWithInterfaceConstraint<Derived> genericObj2 = new GenericWithInterfaceConstraint<Derived>();
        NonGeneric nonGenericObj = new NonGeneric();
        Derived obj = new Derived();

        genericObj.CallMethod(obj);  //calls Base.Method()
        Console.WriteLine(obj.i);

        genericObj.CallMethod2(obj);  //calls Base.Method()
        Console.WriteLine(obj.i);

        genericObj2.CallMethod(obj);  //calls Base.Method()
        Console.WriteLine(obj.i);

        genericObj2.CallMethod2(obj);  //calls Base.Method()
        Console.WriteLine(obj.i);

        nonGenericObj.CallMethod(obj);  //calls Derived.Method()
        Console.WriteLine(obj.i);

        nonGenericObj.CallMethod2(obj);  //calls Base.Method()
        Console.WriteLine(obj.i);

        nonGenericObj.CallMethod3(obj);  //calls Base.Method()
        Console.WriteLine(obj.i);

        obj.Method();  //calls Derived.Method()
        Console.WriteLine(obj.i);
    }
}

Выход

0
0
0
0
1
1
1
2

Ответы на вопрос(4)

Ваш ответ на вопрос