C # 7.0 позволяет записать это как оператор переключения:
switch (object)
{
case Class1 c1:
someMethod(c1);
break;
case Class2 c2:
someMethod(c2);
break;
}
В качестве альтернативы вы можете использовать сопоставление с образцом в C # 7.0:
if (object is Class1 c1) someMethod(c1);
else if (object is Class2 c2) someMethod(c2);
Если вы можете изменить Class1 / Class2 /и т.д., чтобы реализовать некоторый интерфейс посетителя, вы можете использовать шаблон посетителя / двойную диспетчеризацию:
public interface IClass
{
void Visit(IClassVisitor visitor);
}
public interface IClassVisitor
{
void Accept(Class1 c1);
void Accept(Class2 c2);
}
public class Class1 : IClass
{
public void Visit(IClassVisitor visitor) => visitor.Accept(this);
}
public class Class2 : IClass
{
public void Visit(IClassVisitor visitor) => visitor.Accept(this);
}
Затем внедрите IClassVisitor
(и реализуйте Accept(Class1 c1)
и Accept(Class2 c2)
) и вызовите:
object.Visit(this);
и будет вызвана правильная перегрузка Accept
.
(Я являюсь частным поклонником шаблона посетителя по одной простой причине: если вы добавите другую реализацию IClass
,компилятор заставляет вас обновлять каждого из посетителей, поэтому вы не забудете написать какой-нибудь код, который обрабатывает новую реализацию. С помощью оператора switch / if / else вы должны помнить все места, где вы переключаетесь.object
и обновите каждый из них. Таким образом, это выглядит как гораздо меньшее нарушение принципа открытия / закрытия).