如何执行派生类函数?

时间:2011-10-01 04:44:26

标签: c# inheritance overloading derived-class

我们有一个基类:过滤器。 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));
}

然后打印:     

        
  • 过滤
  •     
  • 过滤
  •     ...     

如何让它打印出来呢?     

        
  • distr filter
  •     
  • distr filter
  •     ...     

3 个答案:

答案 0 :(得分:2)

Filter类添加虚拟方法,名为GetName()或类似内容,并在return "distr filter";中以DistrFilterreturn "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 dispatchVisitor Pattern