Либо реализуйте GetFilterText()
как виртуальный метод в Filter
:
class Filter
{
// Can be converted into a property as well.
public virtual string GetFilterText { return "filter"; }
}
class DistrFilter : Filter
{
public override string GetFilterText { return "distr filter"; }
}
Тогда сделайте это:
StringBuilder s = new StringBuilder("<ul>");
foreach (T f in filters)
s.AppendFormat("<li>{0}</li>", f.GetFilterText());
Или, если вы хотите отделить задачу определения текста фильтра от классов Filter
, используйте двойную диспетчеризацию (шаблон посетителя). Это полезно, если у вас могут быть разные типы сервисов фильтрации. Это можно сделать следующим образом:
interface IServiceAcceptor
{
string Accept(FilterService service);
}
public class Filter : IServiceAcceptor
{
string IServiceAcceptor.Accept(FilterService service)
{
return service.GetFilterText(this);
}
}
public class DistrFilter : Filter, IServiceAcceptor
{
string IServiceAcceptor.Accept(FilterService service)
{
return service.GetFilterText(this);
}
}
public class ReportFilter : Filter, IServiceAcceptor
{
string IServiceAcceptor.Accept(FilterService service)
{
return service.GetFilterText(this);
}
}
Тогда к вашим услугам:
public string GetDesc<T>(List<T> filters) where T : IServiceAcceptor
{
if(filters.Count == 0) return String.Empty;
var s = new StringBuilder("<ul>");
foreach (T f in filters)
s.AppendFormat("<li>{0}</li>", f.Accept(this));
s.Append("</ul>");
return s.ToString();
}
Некоторые ссылки: Двойная отправка , Шаблон посетителей