2017-04-11 5 views
7

मैंने एक स्थगित निष्पादन कोड का एक टुकड़ा सरलीकृत किया है, लेकिन आप पृथ्वी पर कैसे जांचते हैं कि इसे कोशिश/पकड़ में लपेटे बिना शून्य/खाली नहीं है?सी # में 'आलसी लोडेड' शून्य आईन्यूमेरेबल के लिए परीक्षण?

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

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

@MrinalKamboj यह एक NullReferenceException फेंक दिया गया है क्योंकि SelectManyIterator को शून्य तत्व के साथ बुलाया जाता है। –

+0

@ आरबी। तो यह मुश्किल है, मेरे उपर्युक्त बिंदुओं में से कोई भी –

उत्तर

3

आप बस अपनी लैम्ब्डा अधिक अशक्त प्रविष्टियों को लचीला बनाने की जरूरत है , क्योंकि यह पूछने जैसा ही है "मैं कैसे कह सकता हूं कि यह विधि NullReferenceException फेंकने के बिना फेंक नहीं देगी?"। कोई अन्य संकेत नहीं होने का एकमात्र तरीका वास्तव में ऐसे तरीकों का आह्वान करता है और परिणाम का निरीक्षण करता है। IEnumerable का आकलन केवल MoveNext कॉल के गुंबद का आह्वान कर रहा है, और इस तरह की कोई भी कॉल किसी भी अपवाद को फेंक सकती है।

+0

पकड़ लेगा यह अच्छा है, लेकिन अगर मैं अभी 'आईन्यूमेरेबल ' तर्क पारित कर रहा हूं तो मुझे लगता है कि मैं अटक गया हूं ... – maxp

+0

@maxp हाँ - एक मौलिक समस्या है 'ienumerable' के निर्माण के साथ। मुझे नहीं लगता कि इसमें कोई फिक्सिंग है। –

2

आप देख सकते हैं प्रगणक से वर्तमान आइटम अशक्त

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

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

यह काम नहीं करेगा - जब आप 'MoveNext()' को फिर से चलाने के लिए कहते हैं तो यह क्रैश हो जाएगा यदि यह 'शून्य' तत्व में आता है। आखिरकार, प्रत्येक तत्व के लिए प्रोजेक्शन फ़ंक्शन का मूल्यांकन किया जा रहा है, और जब इसे शून्य मान के साथ बुलाया जाता है तो यह क्रैश का कारण बनता है - मुझे नहीं लगता कि इसके आसपास कोई भी हो रहा है। –

+2

@ आरबी। डब्ल्यू/ओ 'MoveNext() ', कोई' वर्तमान' नहीं है :)। क्या यह स्क्वायर वन –

+3

पर वापस है यह बहुत गलत जवाब है - 'MoveNext' के पहले' परिभाषित 'से पहले' वर्तमान 'तक पहुंचने से पहले व्यवहार को अपरिभाषित किया गया है - सबसे अधिक संभावना है कि यह हमेशा' शून्य 'देता है। –

3

आप ऐसा नहीं कर सकते है:

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

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

चूंकि लिंक विधियां IENumerable पर विस्तार विधियां हैं, इसलिए आप इन एक्सटेंशन को आगे बढ़ा सकते हैं: एक विस्तार विधि के साथ, एक्सटेंशन प्राप्त करने वाला ऑब्जेक्ट शून्य हो सकता है।

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; 
    } 

तुम भी एक खाली List<TResult> बजाय nullsource==null के लिए लौट सकते हैं।

संबंधित मुद्दे