OrderedDictionary sieht nett aus.
Ich schau mal, was ich damit so hinbekomme.
Vielen Dank!
So sieht es jetzt umgebaut auf OrderedDictionary aus:
public bool removeApplicationAtIndex(int index)
{
return removeItemFromDictionaryAtIndex(this.applicationsDictionary, index);
}
private bool removeItemFromDictionaryAtIndex(System.Collections.Specialized.OrderedDictionary dictToDeleteFrom, int index)
{
// Look if the index makes sense to prevent Exceptions.
if(dictToDeleteFrom.Count < index || index < 0)
{
// Doesn't make sense, stop trying.
return false;
}
try
{
dictToDeleteFrom.RemoveAt(index);
}
catch
{
// Should only occour if dictionary is readonly since out-of-bounds is handled above
return false;
}
return true;
}
Ich bitte um Nachsicht, da ich im normalen Tagesgeschäft maximal 9 Collections zur Verfügung habe und mir spezialisierte Collections weitestgehend unbekannt sind. ;)
pdelvo
Danke für den Tipp mit den Generics. Das hatte ich bereits probiert, doch da muss irgendwo ein Fehler in meiner Vorgehensweise gewesen sein.
chilic
Guter Punkt.
In meinem Fall habe ich ein Dictionary gespeichert.
Die Werte dieses Dictionaries möchte ich in einer ListBox anzeigen.
Da ich faul bin, lasse ich mir einfach aus den Werten eine BindingList erstellen und verheirate diese als Datenquelle mit der ListBox.
public System.ComponentModel.BindingList<string> getApplicationNames()
{
// The simplest way is to create a new BindingList object and paste all dictionary items to it.
System.ComponentModel.BindingList<string> names = new System.ComponentModel.BindingList<string>();
foreach(var item in applicationsDictionary)
{
names.Add(item.Value);
}
return names;
}
...
private void initializeApplicationsList()
{
listOfApplications = applicationAndDevicesListDatasource.getApplicationNames();
listOfApplications.AllowNew = true;
listOfApplications.AllowRemove = true;
listOfApplications.AllowEdit = false;
this.applicationListBox.DataSource = listOfApplications;
}
Wenn jetzt der Benutzer in der ListBox etwas auswählt und den 'Löschen'-Button anklickt, dann soll das gewählte Element naheliegenderweise gelöscht werden - sowohl aus der ListBox als auch aus dem Dictionary.
Ich hoffe einfach, dass in der durch die Iteration erstellten BindingList die Stringobjekte in der Reihenfolge angelegt wurden, wie sie auch im Dictionary anzutreffen sind. Nach mehreren Tests war das auch der Fall.
Weiterhin hoffe ich, dass das Dictionary während der Laufzeit seine interne Anordnung nicht umstrukturiert. Hat es bis jetzt nicht getan und dieses Verhalten steht auch nirgendwo dokumentiert.
Insofern denke ich, dass dieser Ablauf keinerlei Denkfehler enthält.
Wenn dir dennoch einer auffällt bin ich für jeden Hinweis dankbar. :)
ich habe eine kleine Beispielmethode, die wie folgt aussieht:
public bool removeApplicationAtIndex(int index)
{
// Look if the index makes sense to prevent Exceptions.
// FIXME: shouldn't it be Count<index, since Count==index provides an OutOfBoundsException?
// FIXME: shouldn't the index be checked to be larger than -1?
if(this.applicationsDictionary.Count ≤ index)
{
// Doesn't make sense, stop trying.
return false;
}
// Gather all keys in an array to determine which key represents this index.
System.Collections.Generic.Dictionary<long,string>.KeyCollection kc = this.applicationsDictionary.Keys;
int current = 0;
foreach(long item in kc)
{
if(current == index)
{
// This key matches this index, so remove the object with this key.
this.applicationsDictionary.Remove(item);
return true;
}
current++;
}
// Index not found. Should never happen, but who knows.
return false;
}
Jetzt möchte ich dieselbe Funktionalität, also ein Mapping zwischen einem Array-Index und einem Dictionary-Key, auch für andere Dictionaries hinbekommen.
Mein erster Ansatz ist, die spezialisierten Methoden aufzuweichen und damit eine allgemeine Methode aufzurufen.
public bool removeApplicationAtIndex(int index)
{
return removeValueInDictAtIndex(this.applicationsDictionary, index);
}
public bool removeValueInDictAtIndex(System.Collections.Generic.Dictionary<object,object> dict, int index)
{
...
if(dict.Count ≤ index)
...
System.Collections.Generic.Dictionary<object,object>.KeyCollection kc = dict.Keys;
...
foreach(var item in kc)
...
dict.Remove(item);
...
}
Nur leider habe ich unterschiedliche Dictionaries.
Eines arbeitet mit <string,string>, eines mit <long,string>, eines mit <string,long> und so weiter. Deshalb ist dieser Ansatz nicht praktikabel.
Wie kann ich es realisieren, dass ich obiges Gewirr (das vermutlich auch ein paar Fehler enthält, siehe //FIXME: ^^) nur einmalig tippen muss und trotzdem unterschiedliche Dictionaries abgearbeitet werden können?
Gegeben ist ein String, welcher via BitConverter.ToString() eine Byte-Representation enthält.
Nun ist das Internet und die Dokumentation voll mit Tipps und Tricks, mit denen man aus den Strings ein Bytearray basteln kann.
Nur möchte ich genau das nicht.
Ich möchte, dass der String "00-00" in das Bytearray { 0x00, 0x00 } gewandelt wird.
Also simpel die Striche raus (String.Split() hilft da) und die Werte 1:1 als Bytes übernommen.
Nun, Byte.Parse() tuts nicht.
So baut es mir zwar ein { 0x00, 0x00 }, aber gibt mir eine System.FormatException, wenn String keine darstellbare Zahl ist. "255" würde also angenommen, "FF" hingegen nicht.
Auch die Encoder.GetByte() liefern mir genau das: die Byte-Werte der Zeichen.
Die BitConverter.GetBytes() will dafür ausschließlich irgendwelche Zahlen, keine Strings.
Welche Möglichkeit habe ich, einen String wie "01-02-03-F1-F2-FF" in das ByteArray { 0x01, 0x02, 0x03, 0xF1, 0xF2, 0xFF } zu wandeln?
Geht das zufällig mit Bordmitteln und ich suche einfach nach den falschen Schlagworten?
Oder muss ich mir in einer Switch-Anweisung jedes einzelne Dupel selbst zusammenketten?
Genial, danke!
Ah, unter den Hinweisen zum Stream steht's ja auch. Schade, dass die IDE sich darüber ausschweigt.
Umso besser, dass einem geholfen wird.
FF-30-01-00-00-00-03-00-00-00-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F-10-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F-10-FE-00-00-00- und weitere 210 Nullbytes
Daran stören mich eigentlich genau zwei Dinge:
a) warum wird an Position 3 aus meinem Integer, den ich frecherweise auch noch auf nen 32 Bit Int caste, einfach ein Byte gemacht?
Sei message.Length=256, dann heißt das Byte einfach '00', ein vorheriges Umbauen und Nutzen von UInt32 ändert auch nix, obwohl im Folgenden an Position 4 an ordentlicher Integer mit den erwarteten 4 Byte erstellt wird.
b) und wo kommt dieser Rattenschwanz an 00-Blöcken her?
Irgendwie helfen mir die zur Verfügung stehenden Dokumente in diesem Fall leider nicht weiter...
Hat jemand nen Tipp, wie ich besagte Problemchen beseitigt bekomme?
Also generell: wenn Mehrfachvererbung möglich ist darf man sie auch nutzen. Sonst gäbe es sie ja nicht. ;)
In diesem Fall ist es aber so wie FZelle schon schrieb: du leitest von einer abstrakten Klasse ab und implementierst ein Interface. Das ist, soweit ich die Literatur verstanden habe, gängige Praxis.
Ich verstehe nur den Sinn hinter deinen Interfaces (aktuell) nicht.
Das IXYZ Interface verstehe ich, da ja sowohl XYZ als auch Point und Vector dieses Interface implementieren.
Warum du dir aber IVector und IPoint Interfaces angelegt hast verstehe ich nicht.
Du benutzt sie ja nur in Vector und Point, und da kannst du es auch eigentlich ohne Interface einfach runtertippen.
Klingt nach einem ScriptTimeout auf dem Backendserver.
Dieses sollte vom Apache geworfen werden und Strato dürfte das selbstverständlich nicht ausgeben lassen.
Dafür spricht, dass es mit älteren (weniger) Daten läuft.
So spontan würde ich die 'UpdaterUpdateRoutine' in die (aktualisierte) Programm.exe einbauen.
Sobald also die Programm.exe gestartet wird schließt diese die Update.exe, ersetzt sie und startet sie neu.
Quasi ein gegenseitiges Aktualisieren.