2017-05-04 7 views
0

나는 다음과 같은 한 확장 기능 :수익을 사용하여 빈 콜렉션을 반환하려면 어떻게해야합니까?

var readFields = dsReader.Select(r => 
{ 
    var serviceResponse = myService.Decrypt<DateTime>(r.GetString(DATE_VALUE), r.GetInt32(DEK_ID)); 

    if (serviceResponse.IsSuccessful) 
    { 
     return new DataField<DateFieldValue> 
     { 
      FieldValue = new DateFieldValue { Data = serviceResponse.Value } 
     }; 
    } 
    return null; 
}); 

if (!readFields.IsCollectionNullOrEmpty()) 
         returnFinalFields.AddRange(readFields); 

여기에 직면 serviceResponse.IsSuccessful이 거짓 인 경우에도 readFields의이 포함 된 비어 있지 않은 것입니다 오전 문제 :

public static IEnumerable<T> Select<T>(this IDataReader reader, 
           Func<IDataReader, T> selector) 
{ 
    while (reader.Read()) 
    { 
     yield return selector(reader); 
    } 
} 

처럼 사용되는 null 인 항목을 가지는 열거 형 여기서 빈 콜렉션을 반환 할 수있는 방법이 있습니까?

+3

'Enumerable.Empty (); ' –

+0

참조)합니다 (reader.Read 전에 확인하는 방법이 있나요 데이터가 있으면 잠시 들어가기 전에 null을 반환할까요? – Neil

+2

@Neil은 예상되는'IEnumerable '에서 null을 반환하는 것은 거의 항상 반대 패턴입니다. –

답변

0

재미있는 (잘못?)를 Select의 사용. 귀하의 문제는 IsSuccessfulfalse 일 때 Select 대표단에서 null을 반환하는 것입니다. 이후 옵션을 Select의 위임에서 값을하지 않는 반환하지 때문에, 필터 :

var readFields = dsReader.Select(r => { 
    var serviceResponse = myService.Decrypt<DateTime>(r.GetString(DATE_VALUE), r.GetInt32(DEK_ID)); 

    if (serviceResponse.IsSuccessful) 
     return new DataField<DateFieldValue> { 
      FieldValue = new DateFieldValue { Data = serviceResponse.Value } 
     }; 
    else 
     return null; 
}).Where(df => df != null); 
1

Select 메서드는 반환 된 결과를 검사하여 유효 할 때만 값을 반환 할 수 있습니다. 예를하지 null를 들어 :

로 Servy에 의해 언급했지만
public static IEnumerable<T> Select<T>(this IDataReader reader, Func<IDataReader, T> selector) 
    where T:class 
{ 
    while (reader.Read()) 
    { 
     var res = selector(reader); 
     if(res!=null) 
      yield return res; 
    } 
} 

, 일반적으로 일반 Select에 속하지 않는 것이라고. 이 방법은 혼동을 피하기 위해 SelectValidValues과 같은 것으로 불릴 수 있습니다.

또 다른 방법은 lambda 매개 변수에 결과가 모두 포함 된 튜플을 반환하는 것입니다. 또 다른 방법은 유효한 값을 확인하는 선택적 매개 변수 (값 또는 추가 조건 자 함수)를 사용하는 것입니다.

+1

그러면 더 이상 선택하지 않습니다. 이것은'Select' 메소드에 속하지 않습니다. – Servy

+1

@Servy 실제로,하지만 OP는 어떻게'선택'이 행동해야하는지 다른 아이디어가 있을까요? 'SelectNotEmpty'라는 이름으로 이름을 바꾸면 공개 코드에 적합합니다. –

+0

@AlexeiLevenkov 그건 그냥 새로운 문제를 만들고있어. LINQ에는 'SelectNotEmpty' 메서드가없는 이유가 있습니다. 투영하려는 경우 투영 방법을 사용하고, 필터링하려면 필터 방법을 사용하십시오. 서로 관련이없는 두 가지 작업을 수행하는 단일 방법으로 결합하지 마십시오.또한 실패한 응답의 표현으로 'null'값을 사용하는 것은 여전히 ​​의미 상으로 잘못되었습니다. * 그 문제를 해결하는 것입니다. – Servy

2

여기 실제 문제는 null 값을 선택하지 않으려는 것입니다. 서비스에 대한 응답이 없습니다. 당신은 당신의 쿼리의 일부로서 성공적인 응답을 필터링 할 수 있습니다 :

var readFields = from r in dsReader 
    let serviceResponse = myService.Decrypt<DateTime>(r.GetString(DATE_VALUE), r.GetInt32(DEK_ID)) 
    where serviceResponse.IsSuccessful 
    select new DataField<DateFieldValue> 
    { 
     FieldValue = new DateFieldValue { Data = serviceResponse.Value } 
    }; 
+0

또는 람다 구문'var readFields = dsReader.Select (r => myService.Decrypt (sr => sr.IsSuccessful) .Select (새 DataField {FieldValue = 새 DateFieldValue {Data = serviceResponse.Value}}); ' – NetMage

+0

BTW, 더 우아한 반전 문제. – NetMage