Это проблема ковариации?
Нет, это проблема статической или динамической отправки. Статическая диспетчеризация означает, что перегруженный вызов метода привязан к соответствующему типу во время компиляции на основе типа переменной , переданной в:
class Base { }
class Derived : Base { }
class Foo
{
void Test()
{
Base a = new Base();
Overload(a); // prints "base"
Derived b = new Derived();
Overload(b); // prints "derived"
// dispatched based on c's declared type!
Base c = new Derived();
Overload(c); // prints "base"
}
void Overload(Base obj) { Console.WriteLine("base"); }
void Overload(Derived obj) { Console.WriteLine("derived"); }
}
Динамическая диспетчеризация означает, что функция связана во время выполнения на основе фактического типа объекта, хранящегося в переменной:
class Base
{
public virtual void Override() { Console.WriteLine("base"); }
}
class Derived : Base
{
public override void Override() { Console.WriteLine("derived"); }
}
class Foo
{
void Test()
{
Base a = new Base();
a.Override(); // prints "base"
Derived b = new Derived();
b.Override(); // prints "derived"
// dynamically dispatched based type of object stored in c!
Base c = new Derived();
c.Override(); // prints "derived"
}
void Overload(Base obj) { Console.WriteLine("base"); }
void Overload(Derived obj) { Console.WriteLine("derived"); }
}
Последний отпечаток показывает разницу между ними. C #, как и большинство языков ООП на основе классов, поддерживает только динамическую диспетчеризацию для неявного параметра this
(называемого «одиночной диспетчеризацией»). Другими словами, переопределенные методы отправляются динамически, но перегружены методов нет.
Типичное решение для фальсификации множественных отправок на языках с одной отправкой - использование шаблона посетителя , который подойдет вам здесь.