2012-02-17 12 views
16

क्या किसी को पता है कि सी # में एक रिवर्स एन्यूमेरेटर शामिल करने के लिए कोई विशिष्ट कारण या डिज़ाइन निर्णय नहीं था? यह बहुत अच्छा होगा अगर सी ++ reverse_iterator के बराबर था, जैसे कि एन्युमरेटर सी ++ iterator के बराबर है। संग्रहों की जा रिवर्स दोहराया जा सकता है बस IReverseEnumerable की तरह कुछ को लागू होता है और एक तरह कुछ कर सकता है:सी # में कोई रिवर्सएन्यूमेरेटर क्यों नहीं है?

List<int>.ReverseEnumerator ritr = collection.GetReverseEnumerator(); 
while(rtir.MoveNext()) 
{ 
// do stuff 
} 

इस तरह, आप बल्कि एक के लिए इंडेक्सर का उपयोग करने से एक ही तरीके से सूचियों और LinkedLists पुनरावृति करने में सक्षम होगा और इस प्रकार दूसरे के लिए पिछले लिंक बेहतर abstraction

+1

दिलचस्प सवाल है, 'MoveNext (' एक रिवर्स प्रगणक के लिए एक विरोधाभास प्रतीत थोड़े हैं हालांकि मैं साथ संगतता के लिए लगता है कि '' foreach' GetReverseEnumerator() 'विधि वास्तव में अभी भी करने के लिए होगा एक 'आईएन्यूमेरेटर' वापस लौटाएं और इस प्रकार उस विधि की आवश्यकता होगी, भले ही 'MovePrevious()' मेरे दिमाग के लिए अधिक उचित लगेगा – RobV

+2

रिवर्स linq एक्सटेंशन विधि है जो कुछ समान प्राप्त करती है ... – RQDQ

+3

'IList ' को लागू करने वाले प्रकारों पर हमें मिलता है linq से एक कुशल 'रिवर्स'। दुर्भाग्य से हर प्रकार जो 'रिवर्स' को कुशलता से कार्यान्वित नहीं कर सकता है, 'IList 'को भी कार्यान्वित कर सकता है। उदाहरण के लिए एक दोगुनी लिंक्ड सूची। इसलिए मैं सहमत हूं कि उन संग्रहों को 'रिवर्स()' विधि में बनाया गया है, यह अच्छा होगा। – CodesInChaos

उत्तर

21

यह लागू करने के लिए पूरी तरह से संभव होगा। व्यक्तिगत रूप से, मैं लगभग कभी विपरीत नहीं करता। अगर मुझे ऐसा करने की ज़रूरत है, तो मैं पहले। (पहले) कॉल करता हूं। शायद यही वह है जो .NET बीसीएल डिजाइनरों ने भी सोचा था।

सभी सुविधाएं डिफ़ॉल्ट रूप से अनुपूरक हैं। उन्हें डिज़ाइन, कार्यान्वित, परीक्षण, दस्तावेज और समर्थित करने की आवश्यकता है। - रेमंड चेन

और यही कारण है कि आप ऐसी सुविधाओं को लागू नहीं करते हैं जो कम उपयोगिता प्रदान करते हैं। आप सबसे महत्वपूर्ण विशेषताओं (जैसे फ्रंट-टू-बैक पुनरावृत्त) के साथ शुरू करते हैं। और आप कहीं भी रुकते हैं जहां आपका बजट समाप्त हो जाता है या जहां आप सोचते हैं, जारी रखने के लिए समझ में नहीं आता है।

ऐसी कई चीजें हैं जो .NET बेस क्लास लाइब्रेरी में नहीं हैं। .NET 4 तक भी File.EnumerateLines नहीं था। और मैं यह कहने का साहस करता हूं कि ज्यादातर लोगों के लिए इस तरह की कार्यक्षमता रिवर्स पुनरावृत्ति से अधिक महत्वपूर्ण है।

ऐसा हो सकता है कि आप किसी ऐसे व्यवसाय डोमेन में काम कर रहे हों जहां रिवर्स पुनरावृत्ति सामान्य है। मेरा अनुभव विपरीत है। एक ढांचा डिजाइनर के रूप में आप केवल अनुमान लगा सकते हैं कि आपके ढांचे का उपयोग कौन करेगा और इन लोगों की क्या मांग होगी। रेखा खींचना मुश्किल है।

+2

क्या इसे 'फ़ाइल। रीडलाइन' नहीं कहा जाता है? – nawfal

11

यह उपलब्ध नहीं है क्योंकि आईनेमरेबल एक अग्रेषित केवल इटरेटर है। इसमें केवल MoveNext() विधि है। इससे इंटरफ़ेस बहुत सार्वभौमिक और लिंक का मूल बनाता है। बहुत सारे वास्तविक विश्व संग्रह हैं जिन्हें पीछे की ओर नहीं किया जा सकता है क्योंकि इसके लिए संग्रहण की आवश्यकता होती है। उदाहरण के लिए अधिकांश धाराएं इस तरह हैं।

लिंक रिवर्स() एक्सटेंशन विधि के साथ समाधान प्रदान करता है। यह पहले तत्वों को संग्रहित करके काम करता है, फिर उन्हें पीछे की तरफ घुमाता है। हालांकि यह बहुत अपमानजनक हो सकता है, इसके लिए ओ (एन) भंडारण की आवश्यकता होती है। यह संग्रह के लिए संभावित अनुकूलन अनुपलब्ध है जो पहले ही अनुक्रमित है। आप कौन सा ठीक कर सकते हैं:

static class Extensions { 
    public static IEnumerable<T> ReverseEx<T>(this IEnumerable<T> coll) { 
     var quick = coll as IList<T>; 
     if (quick == null) { 
      foreach (T item in coll.Reverse()) yield return item; 
     } 
     else { 
      for (int ix = quick.Count - 1; ix >= 0; --ix) { 
       yield return quick[ix]; 
      } 
     } 
    } 
} 

नमूना उपयोग:

 var list = new List<int> { 0, 1, 2, 3 }; 
     foreach (var item in list.ReverseEx()) { 
      Console.WriteLine(item); 
     } 

आप LinkedList के लिए एक विशेषज्ञता बनाने के लिए है, क्योंकि यह IList <> लागू नहीं करता है चाहता हूँ, लेकिन अभी भी त्वरित पीछे की ओर अंतिम के माध्यम से यात्रा की अनुमति देता है और लिंक्ड लिस्ट नोड। पूर्व गुण। हालांकि उस वर्ग का उपयोग न करने के लिए यह बेहतर है, लेकिन इसमें लुसी सीपीयू कैश इलाका है। जब आपको सस्ते आवेषण की आवश्यकता नहीं होती है तो हमेशा सूची <> का पक्ष लें।यह ऐसा दिखाई दे सकता:)

public static IEnumerable<T> ReverseEx<T>(this LinkedList<T> list) { 
     var node = list.Last; 
     while (node != null) { 
      yield return node.Value; 
      node = node.Previous; 
     } 
    } 
+1

धन्यवाद हंस, ग्रेट कोड! यदि आप चाहते हैं कि आप हाल ही के साथ अपना कोड अपडेट कर सकें: IReadOnlyList। –

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