2010-04-26 10 views
5

Ich portiere eine Bibliothek von C++ nach C#. Die alte Bibliothek verwendet Vektoren aus C++ und in der C# verwende ich generische Wörterbücher, weil sie eigentlich eine gute Datenstruktur für das sind, was ich mache (jedes Element hat eine ID, dann benutze ich einfach TypeDictionary = Dictionary<String, Type>;). Jetzt benutze ich in dem C# -Code eine Schleife wie dieseWie kann man wissen, ob ein Enumerator das Ende der Sammlung in C# erreicht hat?

, um durch die Elemente der Auflistung zu durchlaufen. Das Problem ist, dass in bestimmten Fällen, die ich überprüfen müssen, ob eine bestimmte enumerator das Ende der Sammlung, in C erreicht hat ++ Ich würde einen Scheck wie dies getan hat:

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

Aber ich weiß einfach nicht, wie man Behandeln Sie diese Situation in C#, irgendwelche Ideen?

Danke
Tommaso

Antwort

3

Sie wissen, dass Sie am Ende eines Iterators, wenn MoveNext() kehrt false sind. Andernfalls müssen Sie auf eine aussagekräftigere Datenstruktur wie IList<T> aktualisieren.

4

Ich habe eine "Smart Iterator" -Klasse in MiscUtil, die Sie nützlich finden können. Sie können testen, ob Sie gerade den Anfang oder das Ende der Sequenz und den Index innerhalb der Sequenz betrachten. Weitere Informationen finden Sie unter usage page.

Natürlich können Sie in den meisten Fällen manuell mit dem Ergebnis MoveNext() davonkommen, aber gelegentlich ist die zusätzliche Kapselung praktisch.

Beachten Sie, dass dieser Iterator notwendigerweise immer einen Wert mehr verbraucht als er geliefert hat, um zu wissen, ob er das Ende erreicht hat oder nicht. In den meisten Fällen ist das kein Problem, aber beim Debuggen kann es gelegentlich zu seltsamen Erfahrungen kommen.

+0

Vielen Dank für Ihre Bibliothek, habe ich es vorgemerkt, aber für diese Zeit werde ich nur mit der schnellen Lösung gehen. :) – tunnuz

1

Aus C++ kommend sind Sie möglicherweise nicht auf dem neuesten Stand der C# -Syntax. Vielleicht könnten Sie einfach das foreach-Konstrukt verwenden, um den Test alle zusammen zu vermeiden. Der folgende Code wird für jedes Element in Ihrem Wörterbuch einmal ausgeführt werden:

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

Mit dem Dekorateur Muster einen Wert zu halten, wenn der Enumerator beendet hat, ist ein gültiger Ansatz. Da IEnumerator implementiert ist, werden Sie keine Schwierigkeiten haben, es in Ihrem Code zu ersetzen.

Hier ist eine Testklasse:

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 ** oder? Tippfehler? Sollte Enumera ** t ** oder – IlPADlI

+1

sein Ja, wenn man bedenkt, dass das Beispiel in Englisch geschrieben wurde, ist es ein Tippfehler (obwohl es in meiner Muttersprache das Wort für "Enumerator" ist). Es ist jedoch der Klassenname, daher hat dies keine Auswirkungen auf das Ergebnis. – Fabio

Verwandte Themen