Это довольно сложная проблема, чтобы попытаться решить ее в общем. Вы можете подумать о соединении шаблона Visitor, который позволяет добавить функциональность к графу объектов, с шаблоном Chain of Responsibility, который позволяет разделить ответственность за выполнение задачи на несколько объектов, а затем динамически направлять запросы к правый обработчик.
Если вы это сделаете, вы сможете сгенерировать простую, специфичную логику дифференцирования для каждого типа без единого массивного класса, который обрабатывает все ваши задачи дифференциации. Также было бы легко добавить обработчики в дерево.
Самое приятное то, что у вас все еще может быть ссылка в цепочке ответственности для "плоских" объектов (объектов, которые не являются коллекциями и в основном имеют свойства), и именно в этом случае отражение поможет вам в любом случае. Если в вашем «всеобъемлющем» случае используется простое сравнение на основе отражений, а в «особых» случаях используются такие вещи, как списки, словари и наборы, то у вас будет гибкое, поддерживаемое и недорогое решение.
Для получения дополнительной информации: