2017-04-11 104 views
7

Bir ertelenmiş yürütme kodunun bir parçasını sadeleştirdim, ancak aşağıdakileri nasıl kontrol edersiniz, aşağıdakileri deneme/yakalamada sarmadan boş/boş değil? sýralayýcý güncel öğe Bunu yapamaz'Tembel yüklü' null IE numarasında test edilemiyor C#?

string[] nullCollection = null; 
IEnumerable<string> ienumerable = new[] { nullCollection }.SelectMany(a => a); 

bool isnull = ienumerable.GetEnumerator().Current == null; 
if (!isnull) 
{ 
    bool isany = ienumerable.Any(); 
} 
+0

@MrinalKamboj SelectManyIterator null öğesiyle çağrıldığı için atılan bir NullReferenceException var. –

+0

@RB. o zaman onun zor, benim yukarıdaki puanların hiçbiri tutmaz –

cevap

3

Sadece boş girişler için lambda daha esnek hale getirmek için gerek Çünkü bu aynı soruyu sormakla aynı şeydi: "Bu yöntemin, NullReferenceException'u çağırmadan nasıl atamayacağını söyleyebilirim?" Başka hiçbir ipucuna sahip olmanın tek yolu aslında bu tür yöntemleri çağırmak ve sonucu gözlemlemek. IEnumerable numaralandırılıyor, numaralandırıcısına yalnızca MoveNext çağrıları çağırıyor ve bu tür çağrılar herhangi bir istisna oluşturabilir.

+0

Bu güzel, ama ben sadece bir IEnumerable 'argümanını geçtiysem sanırım sıkışmışım ... – maxp

+0

@maxp Evet - temel bir problem var ienumerable'ın inşası ile. Düzeltici olduğunu sanmıyorum. –

2

kontrol edebilirsiniz:

string[] nullCollection = null; 
    IEnumerable<string> ienumerable = new[] { nullCollection }.SelectMany(a => a); 

    bool isnull = ienumerable == null; //returns false 
    bool isany = ienumerable.Any(); //throws an exception 
+1

Bu işe yaramaz - "MoveNext()" dediğinizde, bir "boş" öğesiyle karşılaşırsa çökecektir. Sonuçta, projeksiyon fonksiyonu her eleman için değerlendirilecek ve bir null değeriyle çağrıldığında bir çökmeye neden olacak - bunun etrafında bir şey olduğunu düşünmüyorum. –

+2

@RB. W/o 'MoveNext()', 'Current' :) yok. Bu kare geri döndü Bir –

+3

Bu oldukça yanlış bir cevaptır - 'CurrentN önce 'MoveNext' un tanımsız davranışı vardır - büyük olasılıkla burada her zaman 'null' döndürür. –

3

null ise

IEnumerable<string> ienumerable = new[] { nullCollection } 
    .SelectMany(a => a ?? Enumerable.Empty<string>()); 

bool isany = ienumerable.Any(); // Sets isany to 'false' 
0

Linq yöntemleri IEnumerable üzerinde uzantı yöntemleri olduğundan, bu uzantıları daha da sarabilirsiniz: bir uzantı yöntemiyle, uzantıyı alan nesne boş olabilir.

public static IEnumerable<TResult> SafeSelectMany<T, TCollection, TResult>(
      this IEnumerable<T> source, 
      Func<T, IEnumerable<TCollection>> collectionSelector, 
      Func<T, TCollection, TResult> resultSelector) 
    { 
     if (source == null) 
     { 
      return null; 
     } 
     IEnumerable<TResult> result = source.SelectMany(collectionSelector, resultSelector); 
     return result; 
    } 

Ayrıca source==null için boş List<TResult> yerine null geri dönebilirler.