2011-10-01 2 views
3

우리는 기본 클래스가 있습니다. 필터. 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 필터
      • DISTR 필터
      • ...

    답변

    1

    하나가 Filter에 가상의 방법으로 GetFilterText()을 구현 :

    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()); 
    

    또는 경우를 당신은 필터 텍스트를 지정하는 걱정을 분리하기를 원한다. f 012 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

    2

    return "report filter";ReportFilter에서을의 Filter 클래스에 가상 메서드를 추가 GetName() 또는 유사한 무언가를 불러 구현을 return "distr filter";DistrFilter와. 그런 다음 f.GetName()GetDesc()에 방금 부릅니다.

    또는 GetDesc()if (f is DistrFilter)과 같은 수표를 사용할 수 있지만 특정 파생 클래스를 명시 적으로 확인하고 다르게 처리하는 구조는 일반적으로 좋지 않은 디자인으로 간주됩니다.

    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(); 
        } 
    } 
    
    관련 문제