我们有一个基类:过滤器。 DistrFilter和ReportFilter继承自Filter。
在另一个类FilterService.cs中,我们有两个接受这三种类类型的函数。 FilterService对Filter对象进行操作,但它不会从任何东西继承。
public class FilterService
{
public string GetDesc(List<T> filters) where T : Filter
{
if(filters.Count == 0) return String.Empty;
StringBuilder s = new StringBuilder("<ul>");
foreach (T f in filters)
s.AppendFormat("<li>{1}</li>", GetFilterText(f));
s.Append("</ul>");
return s.ToString();
}
public string GetFilterText(Filter f)
{
return "filter";
}
public string GetFilterText(DistrFilter f)
{
return "distr filter";
}
public string GetFilterText(ReportFilter f)
{
return "report filter";
}
}
public static void main(string[] args)
{
List<DistrFilter> distrFilters = new List<DistrFilters>();
distrFilters.Add(new DistrFilter());
distrFilters.Add(new DistrFilter());
distrFilters.Add(new DistrFilter());
FilterService fs = new FilterService();
Console.WriteLine(fs.GetDescription(distrFilters));
}
然后打印:
如何让它打印出来呢?
答案 0 :(得分:2)
向Filter
类添加虚拟方法,名为GetName()
或类似内容,并在return "distr filter";
中以DistrFilter
和return "report filter";
中的ReportFilter
实施{1}}。然后只需拨打f.GetName()
中的GetDesc()
。
或者,您可以在if (f is DistrFilter)
中使用GetDesc()
之类的检查,但是这种结构,显式检查特定派生类并以不同方式处理它们,通常被认为是设计不佳。
答案 1 :(得分:1)
实现一个类似这样的模式:
public class Filter
{
public virtual string GetDescription()
{
return "filter";
}
}
public class DistrFilter : Filter
{
public override string GetDescription()
{
return "distr filter";
}
}
public class ReportFilter : Filter
{
public override string GetDescription()
{
return "report filter";
}
}
public class FilterService
{
public string GetDescription<T>( List<T> filters )
where T: Filter
{
if ( filters.Count == 0 )
return String.Empty;
StringBuilder s = new StringBuilder( "<ul>" );
foreach ( T f in filters )
s.AppendFormat( "<li>{0}</li>", f.GetDescription() );
s.Append( "</ul>" );
return s.ToString();
}
}
答案 2 :(得分:1)
在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
类分开,请使用double dispatch(访客模式)。如果您可以使用不同类型的过滤器服务,这将非常有用。这可以这样做:
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();
}
一些参考文献:Double dispatch,Visitor Pattern