Warum wird die Methode in der Basisklasse anstelle der neuen Methode in der abgeleiteten Klasse aufgerufen?

Wenn das generische Typargument (einer aufrufenden Klasse oder einer aufrufenden Methode) mit eingeschränkt istwhere T : Base Die neue Methode in T == Derived wird nicht aufgerufen, sondern die Methode in Base.

Warum wird der Typ T beim Methodenaufruf ignoriert, obwohl er vor der Laufzeit bekannt sein sollte?

Aktualisieren: ABER, wenn die Einschränkung eine Schnittstelle wie verwendetwhere T : IBase Die Methode in der Basisklasse wird aufgerufen (nicht die Methode in der Schnittstelle, die auch unmöglich ist).
Das bedeutet, dass das System tatsächlich die Typen erkennen kann, die weit über die Typbeschränkung hinausgehen! Warum geht es dann nicht über die Typeinschränkung hinaus, wenn es sich um eine klassentypisierte Einschränkung handelt?
Bedeutet das, dass die Methode in der Basisklasse, die die Schnittstelle implementiert, ein implizites Überschreibungsschlüsselwort für die Methode hat?

Testcode:

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);
    }
}

Ausgabe:

0
0
0
0
1
1
1
2

Antworten auf die Frage(4)

Ihre Antwort auf die Frage