С учетом комментария к этого ответа из OP, я думаю, что наилучшим подходом было бы создание пользовательского класса контейнера для замены IList<IDisplayable> displayableItems
, который имеет такие методы, как containsHumans()
и containsAnimals()
, так что вы может инкапсулировать неприличный неполиморфный код в одном месте и поддерживать логику в вашей функции Summarize()
чистой.
class MyCollection : List<IDisplayable>
{
public bool containsHumans()
{
foreach (IDisplayable item in this)
{
if (item is Human)
return true;
}
return false;
}
// likewise for containsAnimals(), etc
}
public string Summarize()
{
MyCollection displayableItems = getAllDisplayableItems();
StringBuilder summary = new StringBuilder();
if (displayableItems.containsHumans() && !displayableItems.containsAnimals())
{
// do human-only logic here
}
else if (!displayableItems.containsHumans() && displayableItems.containsAnimals())
{
// do animal-only logic here
}
else
{
// do logic for both here
}
return summary.ToString();
}
Конечно, мой пример слишком прост и надуман. Например, либо как часть логики в ваших операторах Summarize()
if / else, либо, возможно, вокруг всего блока, вы захотите перебрать коллекцию displayableItems
. Кроме того, вы, вероятно, получите более высокую производительность, если переопределите Add()
и Remove()
в MyCollection
и попросите их проверить тип объекта и установить флаг, чтобы ваша функция containsHumans()
(и другие) могла просто возвращать состояние флага и нет необходимости повторять коллекцию каждый раз, когда они вызываются.