Ares - Mi 20.10.10 16:35
Titel: Enumerator für verschachtelte Dictionary-Klasse
Hallo!
Ein Ordner ist durch eine eindeutige ID gekennzeichnet. In jedem Ordner gibt es beliebig viele Elemente. Jedes Element ist ebenfalls durch eine eindeutige ID gekennzeichnet.
Um die Elemente zu verwalten verwende ich eine eigene Klasse. Diese speichert die Elemente in einem verschachtelten Dictionary der Form:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| public class Elements { Dictionary<string, Dictionary<string, Element>> folders;
public Elements() { folders = new Dictionary<string, Dictionary<string, Element>>() }
public void AddElement(string folderID, string elementID, Element element) { Dictionary<string, Element> folder = null;
if (folders.TryGetValue(folderID, out folder) == false) { folder = new Dictionary<string, Element>(); folders.Add(folderID, folder); }
if (folder.ContainsKey(elementID) == false) folder.Add(elementID, element); }
... } |
Ich versuche nun eine ganze Zeit die Klasse Elements so anzupassen, dass man alle enthaltenen Elemente mit einer foreach-Schleife durchlaufen kann. Bislang bin ich leider gescheitert.
Soweit ich das verstanden habe, ist es dafür notwendig, dass die Klasse Elements die Schnittstelle IEnumerable implementiert. Das heißt also, Sie kann über GetEnumerator() einen Enumerator liefern. Ich brauche also noch eine Enemerator-Klasse passent zu Elements:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33:
| public class Elements : IEnumerable { ...
IEnumerator IEnumerable.GetEnumerator() { return (IEnumerator) GetEnumerator(); }
public ElementsEnumerator GetEnumerator() { return new ElementsEnumerator(folders); } }
public class ElementsEnumerator : IEnumerator { private Dictionary<string, Dictionary<string, Element>> folders; private Dictionary<String, Dictionary<string, Element>>.Enumerator foldersEnumerator;
public ElementsEnumerator(Dictionary<string, Dictionary<string, Element>> folders) { this.folders = folders; foldersEnumerator = folders.GetEnumerator; }
public object Current { get { ... } }
public bool MoveNext() { ... }
public void Reset() { ... } } |
Ich weiß nun überhaupt nicht, wie ich Current, MoveNext() und Reset() implementieren soll. Ich wollte eigentlich so vorgehen, dass beim ersten Aufruf über foldersEnumerator der erste "Ordner" aus folders aufgerufen wird. Da dieser "Ordner" wieder ein Dictionary ist, wäre dann hier das erste Element aufgerufen worden.
Bei MoveNext() müsste dann das zweite Element im aktuellen Ordner aufgerufen werden. Erst wenn im aktuellen Ordner keine Element mehr vorhanden sind, müsst der nächste Ordner aufgerufen werden.
Aber wie rufe ich jeweils den ersten Ordner und das erste Element auf?
foldersEnumerator.Current liefert ein KeyValuePair<string, Dictionary<string, Element>>. KeyValuePair<> kann man nicht auf == null prüfen. Wie stelle ich also fest, ob überhaupt ein Ordner vorhanden ist? Muss man in jedem Fall vor dem ersten Aufruf von foldersEnumerator.Current zunächst foldersEnumerator.MoveNext() aufrufen?
Angenommen man hat über foldersEnumerator.Current ein gültiges KeyValuePair<> erhalten. Dann steckt der eigentlichen Ordner in KeyValuePair<>.Value. Dies ist wieder ein Dictionary in dem ich das erste Element haben will. Ich benötige also einen Enumerator für diese Dictionary:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| public object Current { get { KeyValuePair<string, Dictionary<string, Element>> currentFolder = foldersEnumerator.Current; Dictionary<string, Element>.Enumerator currentFolderEnumerator = currentFolder.Value.GetEnumerator(); KeyValuePair<string, Element> currentElement = currentFolderEnumerator.Current;
return currentElement.Value; } } |
currentFolder.Value.GetEnumerator() sollte man nur aufrufen, wenn man den Ordner zum ersten mal betritt. Wird das nächst Element im gleichen Ordner aufgerufen sollte der gleiche Enumerator verwendet werden. Also sollte currentFolderEnumerator global definiert werden.
Aber wie stelle ich nun fest ob ich einen neuen Ordner betrete oder schon in einem Ordner bin? Eigentlich gingt dies, in dem man prüft ob currentFolderEnumerator noch == null ist. In diesem Fall wurde also ein neuer Ordner betreten und der Enumerator muss neu erstellt/abgefragt werden. Aber der == null Vergleich kann für den Enumerator nicht verwendet werden.
Wie kann man also vorgehen?
Besten Dank
Ares