2013-08-14 1 views
2

유창한 구문으로 쓰여졌을 때 같은 줄 내에서 LINQ 문을 "단락"하는 문법적 설탕이나 방법이 있습니까? 예를 들어 nullFirstOrDefault 호출에 의해 반환되면 null을 반환 할 수 있습니까? 그렇지 않으면 나머지 메서드 체인을 계속 진행할 수 있습니까? 문이 Reverse 통화에 발생하는 ArgumentNullException을 던져 있도록임의의 지점에서 기본값이 반환되는 경우 LINQ 쿼리를 중지하십시오.

List<string> testList = new List<string>() { "some", "strings" }; 
var reversed = testList.FirstOrDefault(x => x == "hello").Reverse(); 

FirstOrDefault 호출은 null를 돌려줍니다. 그 시점에서 기본값이 반환되었으므로 Reverse 호출 전에 중지 할 수 있습니까?

는 (나는, 조건 연산자 (?:)를 사용할 수있는 쿼리가 다른 라인으로 나눌 수 있습니다 및 default(T)이 간단한 경우에, Reverse 전에 확인하거나 할 수 있다는 것을 알고 있지만 특정을 누락하는 경우 궁금 해요 더 길고 복잡한 사슬의 특징)

편집 - 이것은 단지 실제 코드의 일부가 아니라 생각을 보여주기위한 예입니다. 라인을 분리하고 수표를 찍는 것이 더 효과적이기 때문에 예외가 발생하지 않도록하고 싶습니다.

+0

이 이해가되지 않습니다 -'FirstOrDefault()가'에만 그래서'() 역, 단일 요소를 반환합니다'여기에 이해가되지 않습니다 ... 당신은 무엇을 어떻게하려고? –

+0

그것은 단지 인정받은 인위적인 예였습니다. 실제로 그 일을하고있는 것이 아니 었습니다. 그러나 메서드 체인을 계속 진행하는 대신 null을 반환해야하는 시나리오였습니다. – keyboardP

답변

4

집합을 단일 항목으로 해결하고 해당 항목을 조작하려고하지만 집합에서 해당 항목을 찾을 수없는 상황을 적절히 처리하는 경우에는 다음과 같이 끝에 FirstOrDefault을 지연시킬 수 있습니다. 이 :

var reversed = testList 
    .Where(x => x == "hello") 
    .Select(x => x.Reverse()) 
    .FirstOrDefault(); 

또는 아이템이 Where 방법에 지정된 조건을 만족 목록에없는 경우 동등

var reversed = testList 
    .Where(x => x == "hello") 
    .Select(Enumerable.Reverse) 
    .FirstOrDefault(); 

null를 반환합니다. 여기서의 성능 차이는 거의 무시할 수 있습니다. testList을 통해 원래 코드보다 더 많은 루핑이 필요하지 않습니다. 일단 첫 번째 요소가 발견되면 결과가 즉시 반환되기 때문입니다.

+1

OP는 문제를 보여주기 위해 약간의 예를 제공한다고 생각합니다. 다른 예로이 문제를 해결할 수 있기 때문에 다른 사례를 제시 할 수 있습니다. –

+1

@ReedCopsey 열거 형이 아닌 문자열을 뒤집기 때문에 –

+0

감사합니다. 제 질문을 명확히했습니다. 킹 킹 (King King)은 이것이 쉽게 풀어 낼 수있는 예에 불과하다는 점에서 옳습니다.하지만 저는 그 특별한 문제에 대한 실제 해결책에 관심이 없습니다. 임의의 지점에서 기본값을 도중에 찾을 수 있고 나머지 LINQ 쿼리가 중지 된 언어 기능이 있는지 궁금합니다. – keyboardP

2

예, FirstOrDefault 대신 First를 사용하십시오. 예외를 일찍 throw합니다.

+0

답장을 보내 주셔서 감사합니다. 그러나 이것은 제가 예외를 피하기위한 아이디어로 찾고있는 것이 아닙니다. 예외가 처리되어야한다면, Reverse 호출 또는 성능 관점에서 쿼리를 여러 행으로 분할하는 것이 가능할 수 있습니다. 나는 나의 질문에 그것을 명확히해야했다. – keyboardP

+1

그러면 대답은 불행히도 아니오입니다. 당신은 퍼포먼스와 퍼포먼스 측면에서 묻는 것처럼 보입니다. 던져진 예외는 실제로 최적입니다. 그 블록에서 오류가 유일한 이유 인 것을 알고 있다면 캐치를 완전히 공백으로 남겨두고 예외 유형을 정의하지 말고 오류를 먹게하십시오. – wilso132

+0

명확히하기 : 쿼리를 분할하고 nulls에 대한 if/then 검사를 수행하는 것은 예외를 먹는 것보다 훨씬 덜 효율적입니다. – wilso132

2

어쩌면 모나드의 C# 버전을 본 것처럼 보입니다. 목록이 "안녕하세요"라는 단어를 포함하지 않는 경우이 사용

public static class MaybeMonadExtensions 
{ 
    public static TResult GetIfNotNull<TInput, TResult>(this TInput o, Func<TInput, TResult> evaluator) 
     where TResult : class 
     where TInput : class 
    { 
     return o == null ? null : evaluator(o); 
    } 
} 

, 당신은

var reversed = testList.FirstOrDefault(x => x == "hello").GetIfNotNull(s => s.Reverse()); 

를 작성하고 그 뜻을 출력 널 수 있습니다.

-1

이 패턴을 시도해보십시오

Where().FirstOrDefault()?.Property 

나는 비슷한 문제를 가지고 내가 설명 패턴을 해결했다.

My code

관련 문제