Polymorfismus v jazyku C# striktně zajišťuje, že na instanci odvozené třídy je vždy volána přepsaná (override) implementace virtuální metody. Toto platí nejen například při přetypování dané instance zpět na typ základní třídy, ale i při volání metody základní třídy pomoci reflection.
Oboje demonstruje následující příklad:
class Base
{
public virtual void Foo() { Console.WriteLine("Base"); }
}
class Derived : Base
{
public override void Foo() { Console.WriteLine("Derived"); }
}
public static void Main()
{
Derived d = new Derived();
Base b = (Base)d;
b.Foo();
typeof(Base).GetMethod("Foo").Invoke(d, null);
Console.ReadLine();
}
Pokaždé je tedy zavolána metoda Derived.Foo, nikoliv Base.Foo.
V normálních případech se snad ani nestane, že by jsme záměrně chtěli toto pravidlo porušit, a potřebovali zvenku na instanci odvozené třídy zavolat skrytou implementaci ze třídy základní. Pokud se do takové situace dostaneme, bude to zpravidla tím, že máme chybný návrh hierarchie našich tříd apod.
Pokud tedy chcete na odvozené třídě base implementaci metody zavolat, obecně platí: Nechtějte to a nedělejte to.
Přestože platí výše uvedené, jak lze takové volání udělat?
Jde to, a to dokonce i bez nutnosti modifikace IL (kdy by se v runtime na Derived třídě “dogenerovala” nová metoda zpřístupňující base.Foo) a podobných záležitostí. Jak na to ukazuje následující kód:
public static void Main()
{
Derived d = new Derived();
var method = typeof(Base).GetMethod("Foo");
IntPtr ftn = method.MethodHandle.GetFunctionPointer();
var action = (Action)Activator.CreateInstance(typeof(Action), obj, ftn);
action();
}
Zde se na instanci třídy Derived skutečně zavolá metoda Base.Foo.