2010-04-26 7 views
5

Przesyłam bibliotekę z C++ do C#. Stara biblioteka używa wektorów z C++, aw C# używam generycznych słowników, ponieważ w rzeczywistości są one dobrą strukturą danych dla tego, co robię (każdy element ma identyfikator, a następnie używam tylko przy użyciu TypeDictionary = Dictionary<String, Type>;). Teraz w kodzie C# używam pętli podobnej do tej, aby wykonać iterację elementów kolekcji. Problemem jest to, że w szczególnych przypadkach trzeba sprawdzić, czy dany wyliczający osiągnął koniec zbiorów, w C++ zrobiłbym czek takiego:Jak sprawdzić, czy moduł wyliczający osiągnął koniec kolekcji w języku C#?

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

Ale ja po prostu nie wiem jak do obsłużyć tę sytuację w języku C#, jakieś pomysły?

Dziękuję
Tommaso

Odpowiedz

3

Wiesz, że jesteś w końcu iteratora gdy MoveNext() powraca false. W przeciwnym razie musisz dokonać aktualizacji do bardziej opisowej struktury danych, takiej jak IList<T>.

4

Mam klasy "inteligentnego iteratora" w MiscUtil, które mogą okazać się przydatne. Pozwala sprawdzić, czy aktualnie patrzysz na początek lub koniec sekwencji oraz indeks w sekwencji. Aby uzyskać więcej informacji, patrz usage page.

Oczywiście w większości przypadków można po prostu uciec z robieniem tego ręcznie przy użyciu wyniku MoveNext(), ale od czasu do czasu przydatna jest dodatkowa enkapsulacja.

Zauważ, że z konieczności ten iterator zawsze pochłonął o jedną wartość więcej, niż uzyskał, aby wiedzieć, czy dotarł do końca. W większości przypadków nie stanowi to problemu, ale może czasami powodować dziwne wrażenia podczas debugowania.

+0

Dziękuję za biblioteki, mam go w zakładkach, ale tym razem po prostu pójdę z szybkiego rozwiązania. :) – tunnuz

1

Wychodząc z C++ możesz nie być na bieżąco ze składnią C#. Być może po prostu możesz użyć konstrukcji foreach, aby uniknąć testu razem. Poniższy kod będzie wykonywany raz dla każdego elementu w swoim słowniku:

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

Stosując wzór dekorator do przechowywania wartości, jeśli wyliczający zakończył jest prawidłowym podejściem. Od kiedy implementuje IEnumerator, nie będziesz miał trudności z zastąpieniem go w swoim kodzie.

Oto klasa Test:

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 ** d ** lub? literówka? Powinien to być Enumera ** t ** lub – IlPADlI

+1

Tak, biorąc pod uwagę, że przykład został napisany w języku angielskim, jest to literówka (chociaż w moim ojczystym języku jest to słowo "wyliczacz"). Jest to jednak nazwa klasy, więc nie ma wpływu na wynik. – Fabio

Powiązane problemy