2012-07-07 5 views
4

이 메서드를 사용하여 일반 목록 <>을 정렬했습니다. 최근 T에서 T의 대상 속성이 nullable 유형 (십진수?) 인 경우 잘못된 결과가 나타났습니다. 어떤 아이디어를 수정하는 방법? 내 직원에 대한 예를 들어 http://www.codeproject.com/Articles/27851/Sorting-Generic-Lists-and-IEnumerables-by-Object-P일반 정렬 코드로 null 가능 유형 정렬

, 널 (NULL) 소수점 재산 시간 개체를 "개체 속성 이름으로 일반 목록 및 IEnumerables 정렬"필 Hustead의 기사에서 코드 위

public void SortList<T>(List<T> dataSource, string fieldName, SortDirection sortDirection) 
{ 
    PropertyInfo propInfo = typeof(T).GetProperty(fieldName); 
    Comparison<T> compare = delegate(T a, T b) 
    { 
     bool asc = sortDirection == SortDirection.Ascending; 
     object valueA = asc ? propInfo.GetValue(a, null) : propInfo.GetValue(b, null); 
     object valueB = asc ? propInfo.GetValue(b, null) : propInfo.GetValue(a, null); 

     return valueA is IComparable ? ((IComparable)valueA).CompareTo(valueB) : 0; 
    }; 
    dataSource.Sort(compare); 
} 

.

Null 허용 시간 107, NULL, 8, 152, 64, 8 , NULL, 64, NULL, 107 널 종류, 152.

nulls는 목록의 시작 부분이나 끝 부분을 정렬해야한다고 생각합니다.

+1

실제 결과와 원하는 결과가 모두 문제가되는 샘플 입력을 제공하십시오. 그리고 왜 List을 처리 할 때 당신의 메소드를 사용하겠습니까? List의'Sort' 메소드를 사용하면 기본 비교기가이 트릭을 수행 할 것입니다. –

답변

4

public static void SortList<T>(List<T> dataSource, string fieldName, SortDirection sortDirection) 
{ 
    PropertyInfo propInfo = typeof(T).GetProperty(fieldName); 
    Comparison<T> compare = delegate(T a, T b) 
    { 
     bool asc = sortDirection == SortDirection.Ascending; 
     object valueA = asc ? propInfo.GetValue(a, null) : propInfo.GetValue(b, null); 
     object valueB = asc ? propInfo.GetValue(b, null) : propInfo.GetValue(a, null); 

     if(valueA == null) 
     { 
      if(valueB == null) 
      { 
       return 0; 
      } 
      else 
      { 
       return asc ? -1 : 1; 
      } 
     } 
     if(valueB == null) 
     { 
      return asc ? 1 : -1; 
     } 

     return valueA is IComparable ? ((IComparable)valueA).CompareTo(valueB) : 0; 
    }; 
    dataSource.Sort(compare); 
} 

홈페이지 문제에 방법을 변경

하면 IComparable 만하고 valueA == null 경우에 대한 valueA을 확인하는 것입니다 - 비교 객체에 상관없이 valueB에 무엇인지, 동일한 없음을 반환합니다. Nullable 값이 boxed되어있을 때 (정확히 여기에서 일어난다) 실제 값 또는 null으로 표시됩니다.

+0

이 메소드를 "Value"(이 속성을'decimal? '과 함께 사용할 때 속성 이름 일뿐입니다)을'fieldName'으로 호출하면'TargetException'이 발생합니다. –

+0

네,하지만 질문은 다소 혼란 스럽습니다. OP는'decimal? '('T'는'Employee','fieldName'는'Hours','Hours'는'decimal?')의 목록이 아니라 nullable 속성을 가진 객체를 정렬합니다. – max

+0

고마워요. 우수 답변과 매우 도움이되는 설명. –

0

nullable 값을 지원하는 위의 (최종) 예제는 내 List에 유용하지만 특정 시나리오에서만 유용합니다. My CustomType에는 네 개의 필드가 있으며, 두 개는 문자열 유형이고 두 개는 DateTime입니다. (null 입력 가능) 유형.

문자열 값 중 하나를 정렬 할 때 훌륭하게 작동합니다. 그러나 nullable DateTime 중 하나를 정렬 할 때? 값은 하나의 DateTime을 정렬합니까? 값은 적절하지만 문자열 값에 대한 정보가 "손실"됩니다!

목록이 지정된 DateTime으로 정렬 된 상태로 남았습니까? 값을 포함하고 있으며 여전히 다른 DateTime을 포함하고 있습니까? 값이 비어 있지만 비어있는 문자열 값?

여기에 아이디어가 있습니까?