2014-11-20 5 views
1

Linq Min 및 Max 확장 메서드가 초기화되지 않은 Null 허용 형식을 처리 할 때와 같은 방식으로 작동하는 이유는 무엇인가 (또는 자유롭게 추측 할 수 있습니까? ... Enumerable Min 및 Max 확장 메서드에 의해 Bewildered 초기화되지 않은 nullable 형식의 동작

new int?[] { null, 1 }.Max();      // 1 as expected 
new int?[] { null, 1 }.Min();      // 1 ?????, why not null ? 

new int?[] { null, null }.Min();     // null, why null now and not above ? 

new int?[] { }.Min();        // null, and no exception ??? 

내가 인정, 나는 특히 NULLABLE가 상관 없어 다음

int? a = null; 
int? b = 1; 

Nullable.Compare(a, b);       // -1, indicating null is smaller then 1 
new int?[] { null, 1 }.OrderBy(x => x).First(); // null, null smaller then 1 

new[] { 0, 1 }.Min();        // 0 as expected 

new int[] { }.Min();        // invalidoperator exception as expected 

지금까지 너무 좋아하지만,을 :

아마도 가장 쉬운 방법은 내가 관찰 한 내용을 보여줄 것입니다 처음에는 유형이 있지만 다른 이야기입니다 :-)

나는 왜 이런 식으로 구현되는지 궁금해합니다 ...

,

건배, 바트

답변

2

이 정의를 초래 Null 허용 소스 코드를 컴파일 할 수 있습니다

그것은 nullable.compare 방법처럼 보인다
public static int Compare<T>(Nullable<T> n1, Nullable<T> n2) where T : struct 
    { 
     if (n1.HasValue) { 
      if (n2.HasValue) return Comparer<T>.Default.Compare(n1.value, n2.value); 
      return 1; 
     } 
     if (n2.HasValue) return -1; 
      return 0; 
    } 

의도적으로 -1을 반환 N1 존재의 경우 null과 n2는 값을가집니다.

마찬가지로이 정의 초래 LINQ 소스 코드를 컴파일 할 수

public static int? Min(this IEnumerable<int?> source) { 
     if (source == null) throw Error.ArgumentNull("source"); 
     int? value = null; 
     foreach (int? x in source) { 
      if (value == null || x < value) 
       value = x; 
     } 
     return value; 
    } 

소스 객체 검사 위에 반복 값은 널 (null)이며, 만약 그렇다면, 값 X를 지정하는 경우 * . null에 대한 비교 중에 숫자를 min 값으로 반환하는 것은 linq의 기본 구현입니다. 질문 에 관해서는

이유이, 내가 널은 값이 아닌 정수 값이 없음을 나타 내기 때문에 그것의 가정하고 (LINQ를 쓴 사람이) 비교가 원래 내장 된 방법에 동의한다는 않습니다. 그들은 아마도 null이 "nulls 및 ints의이 목록에서 최소 "인 것으로 간주 될 정상적인 실행 경로를 찾지 못했습니다.

+0

C. 감사합니다. 그러나 제 질문은 선택의 불일치에 대한 것입니다. 우리에게 Min과 Max를 주었던 "linq guys"도 OrderBy를 작성했습니다. OrderBy는 가치가있는 값 앞에 값이없는 nullable 값을 주문하기 위해 선택합니다 (Nullable.Compare와 동일). 내가 지금까지 발견 한 것은 Min과 Max만이 그 순서를 존중하지 않고, 심지어 자신의 규칙을 어기면, Min 또는 Max를 빈 시퀀스에 사용하는 것이 갑자기 가능하다는 것이다. 왜냐하면 그 타입이 nullable이기 때문이다. 다른 모든 빈 시퀀스는 예외를 생성합니다. –

+1

Null 허용 형식에 대한 비교 구문을 제공 한 이유는 [linq의 orderby에 대한 msdn 항목] (http://msdn.microsoft.com/en-us/library/vstudio/bb534966%28v=vs)에 따르면 때문입니다. 100 % 29.aspx), 형식에 대해 기본 비교자를 사용합니다 (nullable ). 그래서 위에서 설명한 것은 코드에서 두 함수의 출력을 비교할 때 왜 다른 값을 얻는 지에 대한 이유를 설명합니다. –