2010-04-26 6 views
5

मैं सी ++ से सी # तक लाइब्रेरी पोर्ट कर रहा हूं। पुरानी लाइब्रेरी सी ++ से वैक्टर का उपयोग करती है और सी # में मैं सामान्य शब्दकोश का उपयोग कर रहा हूं क्योंकि वे वास्तव में एक अच्छा डेटा संरचना है जो मैं कर रहा हूं (प्रत्येक तत्व में एक आईडी है, तो मैं बस TypeDictionary = Dictionary<String, Type>; का उपयोग करके उपयोग करता हूं)। अब, सी # कोड में मैं इस तरह के एक लूप का उपयोग करता हूं जैसेकैसे पता चलेगा कि एक गणनाकर्ता सी # में संग्रह के अंत तक पहुंच गया है या नहीं?

TypeDictionary.Enumerator tdEnum = MyTypeDictionary.GetEnumerator(); 

while(tdEnum.MoveNext()) 
{ 
    Type element = typeElement.Current.Value; 

    // More code here 
} 

संग्रह के तत्वों के माध्यम से पुनरावृत्त करने के लिए।

if (tdEnum == MyTypeDictionary.end()) // More code here 

लेकिन मैं नहीं जानता कि कैसे: समस्या यह है कि विशेष मामलों में मैं अगर एक निश्चित प्रगणक संग्रह के अंत तक पहुँच गया है की जाँच करने के, सी में आवश्यकता ++ मैं इस तरह एक चेक किया होता है इस स्थिति को सी #, किसी भी विचार में संभाल लें?

धन्यवाद
टोमास्सो

उत्तर

11

यहाँ इस को पूरा करने की एक बहुत सरल तरीका है।

bool hasNext = tdEnum.MoveNext(); 
while (hasNext) { 
    int i = tdEnum.Current; 
    hasNext = tdEnum.MoveNext(); 
} 

मुझे एक ऑनलाइन ट्यूटोरियल मिला जो यह समझने में आपकी सहायता कर सकता है कि यह कैसे काम करता है।

http://www.c-sharpcorner.com/UploadFile/prasadh/Enumerators11132005232321PM/Enumerators.aspx

3

आप जानते हैं कि आप एक इटरेटर जब MoveNext() रिटर्न false के अंत में कर रहे हैं। अन्यथा आपको IList<T> जैसे अधिक वर्णनात्मक डेटा संरचना में अपग्रेड करना होगा।

4

मेरे पास MiscUtil में "स्मार्ट इटरेटर" श्रेणी है जो आपको उपयोगी मिल सकती है। यह आपको यह जांचने देता है कि आप वर्तमान में अनुक्रम की शुरुआत या अंत, और अनुक्रम के भीतर सूचकांक को देख रहे हैं या नहीं। अधिक जानकारी के लिए usage page देखें।

बेशक ज्यादातर मामलों में आप MoveNext() के परिणाम का उपयोग करके इसे मैन्युअल रूप से करने से दूर हो सकते हैं, लेकिन कभी-कभी अतिरिक्त encapsulation काम में आता है।

ध्यान दें कि आवश्यकता के अनुसार, यह इटेटरेटर वास्तव में यह साबित करने के लिए एक और मूल्य का उपभोग करेगा, यह जानने के लिए कि यह अंत तक पहुंच गया है या नहीं। ज्यादातर मामलों में यह कोई मुद्दा नहीं है, लेकिन कभी-कभी डीबगिंग करते समय यह कुछ अजीब अनुभव दे सकता है।

+0

अपने पुस्तकालय के लिए धन्यवाद, मैं इसे बुकमार्क कर दिया है, लेकिन इस बार के लिए मैं सिर्फ त्वरित समाधान के साथ जायेंगे। :) – tunnuz

1

सी ++ से आ रहा है तो आप सी # वाक्यविन्यास पर अद्यतित नहीं हो सकते हैं। शायद आप सभी परीक्षणों से बचने के लिए केवल फोरच निर्माण का उपयोग कर सकते हैं। निम्नलिखित कोड अपने शब्दकोश में प्रत्येक तत्व के लिए एक बार निष्पादित किया जाएगा:

foreach (var element in MyTypeDictionary) 
{ 
    // More code here 
} 
2

एक मूल्य धारण करने के लिए करता है, तो प्रगणक समाप्त हो गया है डेकोरेटर पैटर्न का उपयोग करते हुए एक मान्य तरीका है। चूंकि यह आईन्यूमेरेटर लागू करता है, इसलिए आपको इसे अपने कोड में बदलने की कठिनाइयों को नहीं मिलेगा।

यहाँ एक परीक्षण वर्ग है:

using System.Collections.Generic; 
using Microsoft.VisualStudio.TestTools.UnitTesting; 
using MyDictionary = System.Collections.Generic.Dictionary<int, string>; 
using MyKeyValue = System.Collections.Generic.KeyValuePair<int, string>; 

namespace TestEnumerator 
{ 
    [TestClass] 
    public class UnitTest1 
    { 
     [TestMethod] 
     public void TestingMyEnumeradorPlus() 
     { 
      var itens = new MyDictionary() 
      { 
       { 1, "aaa" }, 
       { 2, "bbb" } 
      }; 
      var enumerator = new EnumeradorPlus<MyKeyValue>(itens.GetEnumerator()); 
      enumerator.MoveNext(); 
      Assert.IsFalse(enumerator.Ended); 
      enumerator.MoveNext(); 
      Assert.IsFalse(enumerator.Ended); 
      enumerator.MoveNext(); 
      Assert.IsTrue(enumerator.Ended); 
     } 
    } 

    public class EnumeradorPlus<T> : IEnumerator<T> 
    { 
     private IEnumerator<T> _internal; 
     private bool _hasEnded = false; 

     public EnumeradorPlus(IEnumerator<T> enumerator) 
     { 
      _internal = enumerator; 
     } 

     public T Current 
     { 
      get { return _internal.Current; } 
     } 

     public void Dispose() 
     { 
      _internal.Dispose(); 
     } 

     object System.Collections.IEnumerator.Current 
     { 
      get { return _internal.Current; } 
     } 

     public bool MoveNext() 
     { 
      bool moved = _internal.MoveNext(); 
      if (!moved) 
       _hasEnded = true; 
      return moved; 
     } 

     public void Reset() 
     { 
      _internal.Reset(); 
      _hasEnded = false; 
     } 

     public bool Ended 
     { 
      get { return _hasEnded; } 
     } 
    } 
} 
+0

Enumera ** डी ** या? लेखन त्रुटि है? Enumera ** टी ** या – IlPADlI

+1

होना चाहिए हाँ, उदाहरण पर अंग्रेजी में लिखा गया था, यह एक टाइपो है (हालांकि मेरी मूल भाषा में यह "गणक" के लिए शब्द है)। हालांकि, यह कक्षा का नाम है, इसलिए यह परिणाम को प्रभावित नहीं करता है। – Fabio

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