Hallo,
ich habe ein Problem bei meinem Dictionary. Warscheinlich stehe ich nur auf der Atlantikleitung aber ich sehe den Fehler einfach nicht. Folgender Code fügt in ein Dictionary einen Key als STring und einen Value als ArrayList ein.
alFieldConfig = new ArrayList();
alFieldConfig.Add(xpNodeIterType.Current.Value);
alFieldConfig.Add(xpNodeIterLgth.Current.Value);
alFieldConfig.Add(xpNodeIterField.Current.GetAttribute("allownull", xpNodeIterField.Current.NamespaceURI));
alFieldConfig.Add(xpNodeIterField.Current.GetAttribute("primarykey", xpNodeIterField.Current.NamespaceURI));
dicBlacklistFieldsComp.Add(xpNodeIterField.Current.Value, alFieldConfig);
Das Problem ist folgendes: Beim ersten durchlauf der for Schleife in der der Code steht schreibt er im Dictionary wunderbar 4 Werte der ArrayList rein.
Bei jedem weiteren durchlauf verändert er aber die Werte um die zuletzt in die ArrayList geschriebenen.
Beispiel:
1 Durchlauf:
Werte im Dictionary:
Key: salutation
Value: ArrayList(String, 255, true, false)
2 Durchlauf:
Werte im Dictionary:
Key: salutation
Value: ArrayList(String, 255, false, false)
Key: sname
Value: ArrayList(String, 255, false, false)
Er überschreibt mir also die ArrayList an Stelle 0 im Dictionary mit der ArrayList von Stelle 1. Warum??
Grüße
Ben
Liegt vielleicht an der Zuweisung von xpNodeIter...
Kannst Du vielleicht mal die ganze Schleife reinstellen?
Hi Eric,
hier mal die Schleife inklusive den umgebenden Try/Catch Block:
try
{
strXPathExpField = this.XPBlacklistImportableFields;
xpNodeIterField = xpnNavField.Select(strXPathExpField);
while (xpNodeIterField.MoveNext())
{
alFieldConfig = new ArrayList();
strXPathExpType = XPBlacklistImportableFieldsType.Replace("?param", xpNodeIterField.Current.Value);
xpNodeIterType = xpnNavType.Select(strXPathExpType);
xpNodeIterType.MoveNext();
strXPathExpLgth = XPBlacklistImportableFieldsLength.Replace("?param", xpNodeIterField.Current.Value);
xpNodeIterLgth = xpnNavLgth.Select(strXPathExpLgth);
xpNodeIterLgth.MoveNext();
alFieldConfig.Add(xpNodeIterType.Current.Value);
alFieldConfig.Add(xpNodeIterLgth.Current.Value);
alFieldConfig.Add(xpNodeIterField.Current.GetAttribute("allownull", xpNodeIterField.Current.NamespaceURI));
alFieldConfig.Add(xpNodeIterField.Current.GetAttribute("primarykey", xpNodeIterField.Current.NamespaceURI));
dicBlacklistFieldsComp.Add(xpNodeIterField.Current.Value, alFieldConfig);
}
}
catch (Exception excE)
{
alFieldConfig = new ArrayList();
alFieldConfig.Add("");
alFieldConfig.Add("");
alFieldConfig.Add("");
alFieldConfig.Add("");
dicBlacklistFieldsComp.Add("", alFieldConfig);
ExceptionHandler.ExceptionThrow (ExceptionHandler.ExceptionType.XMLGetConfigBlacklistFields, excE);
}
Hi ich nochmal,
also ich habe jetzt verschiedene Durchläufe mit dem Debugger gemacht und komme einfach nicht dahinter. Kann es sein, dass das ein allgemeines Problem bei .net ist? Oder was wohl warscheinlicher ist dass ich doch irgendwo einen Denkfehler habe.
Grüße Ben
Also ich seh den Fehler auch nicht, aber mit dem Debugger müsste man doch drauf kommen. Mach einen Durchlauf und setz das ArrayList des ersten Durchlaufs in die Watchlist. Dann müßtest Du doch beim debuggen des 2.Lauf sehen, nach welchem Befehl das Array überschrieben wird.
allgemeines Problem bei .net ist? halt ich für sehr unwahrscheinlich. Dann schon eher ein Problem mit ArrayList.
Aber warum benutzt du solche Konstrukte? Warum nicht eine eigene Struktur definieren, die ist Typsicher und etwaige Fehler werden dir sofort angezeigt.
public struct Item
{
private Bool _allowNull
private Bool _primaryKey
...
}
Dictionary<String,Item> dict=new Dictionary<String,Item>;
Hi,
also das Problem ist ja, dass im Debugger nicht wirklich die Erleuchtung kommt.
Er überschreibt alle ArrayList Values im Dictionary die vor dem aktuellen Item liegen. Und zwar bei der zuweisung des Values in das Dictionary.
Aber die Idee mit dem eigenen Konstrukt ist gut, die werde ich implementieren. Dass ich da nicht gleich drauf gekommen bin. Ich weiß nur nicht ob das mein Problem löst. Schließlich tritt es ja bei der Zuweisung in das Dictionary auf und nicht innerhalb der ArrayList. Es werden ja quasi alle Value Elemente die vor dem aktuellen einfügeitem liegen mit dem aktuellen item überschrieben.
Danke für die Tipps.
Grüße Ben
(Hab eine Idee woran es liegen könnte)
Welchen Typ hat denn xpNodeIterField.Current.Value? Vielleicht ist der Hashcode ja identisch...
Hmm, das währe komisch. Der Type von xpNodeIteField.Current.Value ist String.
Aber ich laufe in der Schleife ja die Knoten durch. Bei jedem Durchlauf wird der Pointer ja auf den neuen Knoten gesetzt. Die xpNodeIterField.Current.Value Werte die mir der Debugger zeigt stimmen auch mit meiner XML Datei überein. Im Dictionary stehen diese Werte als Key auch korrekt drin.
Es währe natürlich super blöd wenn da der Hashcode übereinstimmen würde. Dann währe die Sache klar. Aber eigentlich dürfte der nicht übereinstimmen. Da ja jedesmal ein neuer Knoten selektiert wird.
Ich kann ja mal den Weg über eine String Variable gehen, aber das dürfte auch nichts ändern.
Grüße Ben
Also das mit dem identischen Hashcode glaub ich nicht. Aber das eigene Struct ist eine gute Idee.
Ich würde auch probieren (wenns nicht viel Aufwand ist), statt dem Dictionary eine andere Collection zu nehmen. Nur um mal auszuschließen, dass es irgendeine komische Eigenart der Dictionary-Klasse ist.
Jedenfalls möchte ich Dich bitten, wenn Du die Lösung findest, die noch reinzustellen, da es mich auch interessieren würde.
Hi, also nach langem forschen:
Es liegt definitiv am Dictionary. Kaum zu glauben aber war. Ich habe es mit fixen Werten anstatt einer ArrayList probiert, habe es mit einem String Array probiert. Immer das gleiche. Sobald der zweite Value im Dictionary hinzugefügt wird ändert er den ersten mit den Werten des zweiten ab.
Ich checke es nicht. Versuche jetzt eine Möglichkeit das Dictionary zu umgehen. Wird dann warscheinlich weniger schön aber was will man machen.
Edit: Wenn ich den Value des Dictionaries ändere in einen eigenen Struct funktioniert es einwandfrei. Es muss also irgendwas mit den Hashes zu tun haben. Könnte ich mir vorstellen. Naja, das ist ja zumindest ein ganz praktischer WA.
Grüße
Ben
Hallo bhelbig,
es ist viel einfacher: Variablen von Referenztypen enthalte nur Referenzen auf Objekte. Entsprechend werden auch in Listen und Dictionaries immer nur Referenzen hinzugefügt. Wenn du in ein eine Liste oder Dictionary mehrere Objekte hinzufügen willst, musst du auch mehrere Objekte erzeugen ... und nicht wie du es wohl tust, immer das gleiche Objekt (dessen Werte du nur änderst).
herbivore