2011-12-19 11 views
58

सी # में मैं LINQ और IENumerable का उपयोग करता हूं। और सब अच्छी और अच्छी है (या कम से कम ज्यादातर)।क्या सी # में एक "खाली सूची" सिंगलटन है?

हालांकि, कई मामलों में मुझे खुद को लगता है कि मुझे डिफ़ॉल्ट के रूप में खाली IEnumerable<X> की आवश्यकता है। यही है, मुझे

for (var x in xs) { ... } 

बिना किसी शून्य-जांच की आवश्यकता के काम करना होगा। , है कि अगर कोई सरणी बनाने के साथ किसी भी "अतिरिक्त भूमि के ऊपर" है -

var xs = f() ?? new X[0];    // when xs is assigned, sometimes 
for (var x in xs ?? new X[0]) { ... } // inline, sometimes 

अब, जबकि ऊपर पूरी तरह से मुझे के लिए ठीक है: अब यह है कि क्या मैं वर्तमान में व्यापक संदर्भ पर निर्भर करता है, करते हैं वस्तु मैं सिर्फ परवाह नहीं है - मैं सोच रहा था:

वहाँ "खाली अपरिवर्तनीय IEnumerable/IList" में सी #/सिंगलटन नेट है।? (और, भले नहीं हैं, वहाँ एक "बेहतर" जिस तरह से मामले में ऊपर वर्णित को संभालने के लिए है?)

जावा Collections.EMPTY_LIST अपरिवर्तनीय सिंगलटन है - है, जो इस उद्देश्य को पूरा करता है, हालांकि मैं - "अच्छी तरह से आपके द्वारा लिखा गया" Collections.emptyList<T>() के माध्यम से मुझे यकीन नहीं है कि एक समान अवधारणा सी # में भी काम कर सकती है क्योंकि जेनेरिकों को अलग-अलग संभाला जाता है।

धन्यवाद।

+0

खैर, डारन :) यही वह सूची है जो मुझे सूची/IList पर ध्यान केंद्रित करने के लिए मिलता है और संख्यात्मक/IENumerable नहीं, धन्यवाद - सभी के आसपास वोट। –

+0

http: // stackoverflow।com/प्रश्न/3229698/कैसे-कर सकते हैं-ए-वापसी-एक-खाली IEnumerable –

+1

'सार्वजनिक स्थैतिक कक्षा सरणी {public static केवल पढ़ने के लिए टी [] रिक्त = नई टी [0]; } 'और इसे इस तरह कहा जा सकता है:' ऐरे । लक्षण '। मैंने इसके बारे में पूछा [यहां कोड समीक्षा] (http://codereview.stackexchange.com/q/20417/17039)। –

उत्तर

68

आप के लिए Enumerable.Empty<int>();

देख रहे अन्य समाचार में जावा खाली सूची बेकार है क्योंकि सूची इंटरफेस को उजागर करता है सूची जो अपवाद फेंकने के लिए तत्वों को जोड़ने के लिए तरीके।

+0

यह एक बहुत ही वैध बिंदु है! शायद यह एक नया SO सवाल वारंट करता है? –

+1

आप कुछ सेकंड थे धीमी गति से और कोई प्रलेखन लिंक _ * उंगली शेक * _ ;-) लेकिन svicks टिप्पणी पर विस्तार के लिए स्वीकार करते हैं। –

+0

इसके अलावा अन्य लोगों को अधिक upvotes तो हम भी कर रहे हैं :) मैं एक प्रश्न पोस्ट होगा मिल गया लेकिन मैं बिस्तर पर अभी जा रहा हूँ और मैं सवाल का पालन करने में सक्षम नहीं होगा। इसे खुद क्यों पोस्ट न करें? – Stilgar

17

मुझे लगता है कि आप Enumerable.Empty<T>() देख रहे हैं।

खाली सूची सिंगलटन इतना समझ नहीं लेता है, क्योंकि सूचियां अक्सर उत्परिवर्तनीय होती हैं।

10

मैं एक विस्तार विधि जोड़ने लगता है कि nulls संभाल करने की क्षमता के लिए एक साफ विकल्प धन्यवाद है - कुछ की तरह:

public static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T> list) 
    { 
    return list ?? Enumerable.Empty<T>(); 
    } 

    foreach(var x in xs.EmptyIfNull()) 
    { 
    ... 
    } 
1

माइक्रोसॉफ्ट लागू किया `किसी भी() 'इस तरह (source)

public static bool Any<TSource>(this IEnumerable<TSource> source) 
{ 
    if (source == null) throw new ArgumentNullException("source"); 
    using (IEnumerator<TSource> e = source.GetEnumerator()) 
    { 
     if (e.MoveNext()) return true; 
    } 
    return false; 
} 

यदि आप कॉल स्टैक पर कॉल सहेजना चाहते हैं, तो !Any() पर कॉल करने वाले एक्सटेंशन विधि को लिखने के बजाय, इन तीनों परिवर्तनों को फिर से लिखें:

public static bool IsEmpty<TSource>(this IEnumerable<TSource> source) //first change (name) 
{ 
    if (source == null) throw new ArgumentNullException("source"); 
    using (IEnumerator<TSource> e = source.GetEnumerator()) 
    { 
     if (e.MoveNext()) return false; //second change 
    } 
    return true; //third change 
} 
1

सूचियों के साथ Enumerable.Empty<T>() का उपयोग करना एक कमी है। यदि आप सूची निर्माता में Enumerable.Empty<T> सौंपते हैं तो आकार 4 की एक सरणी आवंटित की जाती है। लेकिन यदि आप सूची निर्माता में Collection खाली खाली करते हैं तो कोई आवंटन नहीं होता है। इसलिए यदि आप अपने समाधान में इस समाधान का उपयोग करते हैं तो संभवतः IEnumerable एस में से एक सूची का निर्माण करने के लिए उपयोग किया जाएगा, जिसके परिणामस्वरूप अनावश्यक आवंटन होगा।

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