Я думаю, что вы можете делать проверки типов в одном месте, потому что это хороший кандидат на полиморфизм.Поскольку и bar
, и bar2
реализуют Ibar
, вы можете изменить определение doSomething
на следующее.
public string doSomething(Ibar item)
{
return item is bar ? ((bar)item).a : ((bar2)item).b.ToString();
}
Теперь, когда вы хотите отобразить его, именно так вы и поступаетеfoo:
public void Method(foo f)
{
Console.WriteLine(f.data);
}
Вы просто передаете свойство data
, поскольку doSomething
будет знать, что с ним делать, когда его получит.
Обновление Основываясь на вашем комментарии, я расширяю код, чтобы использовать сопоставление с образцом, как я предложил.Рассмотрим следующее
public string doSomething(Ibar item)
{
switch (item)
{
case bar b:
return b.a;
case bar2 b:
return b.b.ToString();
case barX b:
return b.X.ToString();
default:
return item.GetType().ToString(); // Just in case...
}
}
, где определение barX равно
public class barX : Ibar
{
public int id {get; set; }
public object X {get; set; }
}
Так что, когда вы добавляете реализацию Ibar, вы делаете это в doSomething.Весь клиентский код останется неизменным, потому что все, что ему нужно сделать, это передать Ibar методу doSomething
, который использует сопоставление с шаблоном в последнем примере, чтобы определить, к какому типу относится элемент, и он действует соответственно.
Окончательное редактирование
Если вы хотите использовать перегрузки, вы можете использовать рефлексию, но я не знаю, подойдет ли вам это определение элегантности.В этом случае он не будет использовать операторы switch и будет находить ваши методы, если они относятся к типу, в котором написан этот. Рассмотрим следующее и измените определение моего ранее предоставленного DoSomething.
public static string ProcessThings(Ibar item)
{
var theType = item.GetType();
Console.WriteLine(theType.Name);
MethodInfo method = typeof(Program).GetMethods()
.Where(x => x.IsStatic && x.Name == "DoSomething" && x.ToString().Contains(theType.Name))
.SingleOrDefault();
var ret = method.Invoke(null, new object[] { item });
return ret?.ToString();
}
public static string DoSomething(barX item)
{
return "foo";
}
public static string DoSomething(bar2 item)
{
return "bar";
}
Таким образом, вы вызываете метод ProcessThings
(переименован для краткости, но он все еще может оставаться как DoSomething), и он выяснит, какую из ваших перегрузок следует вызвать.