В этом случае возникает вопрос: нужно ли, чтобы вызывающая сторона знала конкретный тип или все отображается через общий базовый класс?
В вашем примере все реализации имеют общий абстрактный базовый класс. Если все пользователи могут успешно работать с этим обычным поведением, вы просто проверяете все экземпляры, приведенные к базовому типу. Тем не менее, как вы уже упоминали, в каждом конкретном классе все больше и больше бизнес-логик c. В зависимости от того, насколько (или лучше меньше) это, абсолютно нормально, чтобы позволить это там (это, кажется, ваше текущее решение).
Если это становится все более или более сложным, это был бы хороший способ переместить это в свой собственный класс и / или методы. В этом случае вам нужен какой-то диспетчер, который решает, который заботится о данном объекте. Я начинаю использовать словарь для этих случаев, который работает как диспетчер и имеет данный тип в качестве ключа, а Action или Fun c в качестве значения, подобного этому:
var dispatcher = new Dictionary<Type, Action<Shape>>
{
{ typeof(Rectangle), DoSomethingWithRectangle },
{ typeof(Circle), DoSomethingWithCircle }
}
private void DoSomethingWithRectangle(Shape shape)
{
var rectangle = (Rectangle)shape;
Console.WriteLine($"Rectangle Height: {rectangle.Height} Width: {rectangle.Width}");
}
private void DoSomethingWithCircle(Shape shape)
{
var circle = (Circle)shape;
Console.WriteLine($"Circle Radius: {circle.Radius}");
}
Это просто тривиальный пример. Словарь должен находиться внутри диспетчера, где у вас есть несколько методов для регистрации различных типов, и вместо методов вы также можете регистрировать типы или экземпляры классов, которые могут обрабатывать каждый указанный тип экземпляра c. Если этот вид диспетчеризации все еще не соответствует всем вашим случаям, вы можете взглянуть на MediatR , который формализовал эти вещи намного больше с помощью набора типов-безопасных интерфейсов, которые вы используете для определения типов ввода, желаемое возвращаемое значение и обработчик, способный выполнять эту работу.