2011-12-13 5 views
1

개체 트리에 대한 재귀 함수를 사용하고 있습니다.동적 파생 일반 유형 매개 변수

Object1 
--Object2 
----Object3 
------Object4 

모든 객체가 검증() 메소드가 기본 개체 (추상 클래스), 상속, 그 컬렉션 ITreeCollection에서 상속 : 즉, 내 개체의 컬렉션처럼입니다. 내가 그 수행하는 재귀 함수를 작성했습니다 : 그것은 약자로 내가

+1

사이드 노트 : 피'as' 당신은 꽤 자주 널 심판 예외로 완벽하게 이해할 수 캐스트 예외를 변환 당신이 바로 널 (null)을 확인하지 않는 경우 경우 캐스팅 무관 한 코드 사이트에서 캐스팅에 d. –

+1

다른 쪽 메모 : 항목 목록의 첫 번째 항목의 유효성을 검사 한 후 루프가 반환됩니다. 'Validate'가 false를 리턴하면 나머지 아이템이 유효하게되는 경우에만 리턴하기를 원한다고 생각합니다. 그대로 서서 첫 잎에 대한 결과를 얻을 수 있습니다. –

+2

''T '를'TreeNodeBase'로 대체하면 모든 제네릭이 필요하지 않은 것처럼 보일뿐입니다. – dasblinkenlight

답변

2

우선 내부 기능 (예 : return Validate<T>(((TreeNodeBase)itm).Items))의 형식 매개 변수 T를 유도 할 수있는 방법

private bool Validate<T>(ITreeCollection items) where T : TreeNodeBase 
     { 
      foreach (var itm in items as Collection<T>) 
      { 
       if (((TreeNodeBase)itm).Items != null) 
       { 
        return Validate<T>(((TreeNodeBase)itm).Items); 
       } 
       else return true; 
      } 
      return true; 
     } 

을, 당신은 유형을 사용하지 않는 매개 변수 T이므로 안전하게 제거 할 수 있습니다. 그러나 당신이 어떤 타입의 특정 밸리데이션을하고 싶어 할지도 모른다고 생각합니다. 아마도 이것이 도움이되지는 않을 것입니다. 그러나 T으로 무엇을하고 싶은지 예를 들자면 제안을하기가 어렵습니다.

어쨌든, 여기에 내가 당신이하려고하는 생각 어떤 한 가지 방법이다 : 당신은 동적 키워드 세련되지 얻을이 유형 검사의 일부를 제거 얻을 수

private bool Validate(ITreeCollection items) 
{ 
    foreach (TreeNodeBase node in (IEnumerable) items) 
    { 
     // validate the node itself first 
     if (!Validate(node)) 
     { 
      return false; 
     } 

     if (node.Items != null) 
     { 
      // validate its children 
      if (!Validate(node.Items) 
      { 
       return false; 
      } 
     } 
    } 

    return true; 
} 

private bool Validate(TreeNodeBase node) 
{ 
    if (node is BananaNode) 
    { 
     var bananaNode = (BananaNode) node; 
     //TODO do BananaNode specific validation 
    } 
    else if (node is AppleNode) 
    { 
     var appleNode = (AppleNode) node; 
     //TODO do AppleNode specific validation 
    } 
    else 
    { 
     throw new ArgumentOutOfRangeException("Cannot validate node of type '" + node.GetType().Name + "'."); 
    } 
} 

하지만 그것은 나올까요 약간 혼동 내가 반대 좋을 걸 :

private bool Validate(ITreeCollection items) 
{ 
    foreach (TreeNodeBase node in (IEnumerable) items) 
    { 
     // validate the node itself first 
     if (!Validate((dynamic) node)) // this will call the most appropriate version of Validate 
     { 
      return false; 
     } 

     if (node.Items != null) 
     { 
      // validate its children 
      if (!Validate(node.Items) 
      { 
       return false; 
      } 
     } 
    } 

    return true; 
} 

private bool Validate(BananaNode node) 
{ 
    //TODO do BananaNode specific validation 
} 

private bool Validate(AppleNode node) 
{ 
    //TODO do AppleNode specific validation 
} 

private bool Validate(TreeNodeBase node) 
{ 
    throw new ArgumentOutOfRangeException("Cannot validate node of type '" + node.GetType().Name + "'."); 
}