Учитывая следующую структуру класса:
class Base {}
class DerivedA: Base {}
class DerivedB: Base {}
class Container
{
public List<Base> Items { get; }
}
где список производных объектов со временем растет по мере расширения функциональности моего приложения. Я пытаюсь сделать:
Container container = ReturnsContainer();
foreach (var item in container.Items)
{
doStuff(item);
}
где doStuff(item) перегружен производным типом.
void doStuff(DerivedA) {}
void doStuff(DerivedB) {}
Это не работает, так как компилятор говорит, что «не может преобразовать из «Base» в «DerivedA» и «Лучший перегруженный метод, соответствующий doStuff (DerivedA), имеет некоторые недопустимые аргументы». Лучший подход, который я могу придумать, это:
Container container = ReturnsContainer();
foreach (var item in container.Items)
{
if (item is DerivedA)
{
doStuff((DerivedA)item);
}
else if (item is DerivedB)
{
doStuff((DerivedB)item);
}
}
Любые мысли о том, как я могу сделать это чище? Поскольку мои производные типы со временем будут только расти, мне придется вернуться и добавить к этой длинной структуре if, чтобы продолжать эту работу.
Я думаю, что решение container.Items.OfType‹> приведет к увеличению (и ненужному) снижению производительности по мере увеличения числа производных типов.
Должен ли я использовать общие делегаты для этого? Похоже на слишком сложное решение для того, что чувствуется как должно быть простым полиморфизмом.
Изменить. Для большей ясности предположим, что иерархия базовых и производных типов находится на отдельном уровне API и не может быть изменена (конечные классы). Решение должно работать с существующей структурой наследования и не может расширять базовые и производные объекты. Хотя со временем на уровне API могут появляться новые производные классы.
doStuff(DynamicA)
иdoStuff(DynamicB)
. Смотрите обновление. 28.11.2012Base
- правильный путь. Смотрите ответ@Servy
. Все, что вы делаете, это просто взлом! 28.11.2012