Я работаю над проектом, и у меня есть общий абстрактный тип, который принимает параметр типа, который сам является производным от абстрактного типа. Если вы хотите знать, почему я сделал это, см. этот вопрос .
Я столкнулся с интересной проблемой с перегрузкой метода в производном классе, который определен в абстрактном классе. Вот пример кода:
public abstract class AbstractConverter
where U : AbstractConvertible
where T : AbstractConverter
{
public abstract T Convert(U convertible);
}
public class DerivedConvertibleConverter : AbstractConverter
{
public DerivedConvertibleConverter(DerivedConvertible convertible)
{
Convert(convertible);
}
public override DerivedConvertibleConverter Convert(DerivedConvertible convertible)
{
//This will not be called
System.Console.WriteLine("Called the most derived method");
return this;
}
public DerivedConvertibleConverter Convert(Convertible convertible)
{
System.Console.WriteLine("Called the least derived method");
return this;
}
}
public abstract class AbstractConvertible {}
public class Convertible : AbstractConvertible {}
public class DerivedConvertible : Convertible {}
В приведенном выше примере вызывается перегрузка Convert, которая не существует в абстрактном родительском элементе (и является менее производной). Я ожидал, что будет вызвана самая производная версия от родительского класса.
Пытаясь устранить эту проблему, я натолкнулся на интересное решение:
public abstract class AbstractConverter
where U : AbstractConvertible
{
public abstract AbstractConverter Convert(U convertible);
}
public class DerivedConvertibleConverter : AbstractConverter
{
public DerivedConvertibleConverter(DerivedConvertible convertible)
{
Convert(convertible);
}
public override DerivedConvertibleConverter Convert(DerivedConvertible convertible)
{
System.Console.WriteLine("Called the most derived method");
return this;
}
public DerivedConvertibleConverter Convert(Convertible convertible)
{
System.Console.WriteLine("Called the least derived method");
return this;
}
}
public abstract class AbstractConvertible {}
public class Convertible : AbstractConvertible {}
public class DerivedConvertible : Convertible {}
Когда аргумент производного типа удаляется из базового класса, самая производная версия Convert называется. Я не ожидал такой разницы, поскольку не ожидал, что интерфейс абстрактной версии Convert изменится. Однако я должен ошибаться. Может ли кто-нибудь объяснить, почему возникает эта разница? Заранее большое спасибо.