Was ist der beste Weg, um ein Paar (triple, usw.) von Werten als ein Wert in C # zu verwenden?
-
01-07-2019 - |
Frage
Das heißt, ich möchte ein Tupel von Werten haben.
Der Anwendungsfall in meinem Kopf:
Dictionary<Pair<string, int>, object>
oder
Dictionary<Triple<string, int, int>, object>
Gibt es eingebauten Typen wie Pair oder Dreibettzimmer? Oder was ist der beste Weg, um es umzusetzen?
Aktualisieren Es gibt einige allgemeine Zwecke Implementierungen in den Antworten beschrieben Tupel, aber für Tupel als Schlüssel in Wortlisten Sie sollten Additionaly korrekte Berechnung des Hash-Codes überprüfen. Einige weitere Informationen über die in einem anderen Frage .
Update 2 Ich denke, es lohnt sich auch daran erinnern, dass, wenn Sie einen Wert als einen Schlüssel im Wörterbuch verwenden, sollte es unveränderlich sein.
Lösung
Ich habe eine Tupel Bibliothek in C # implementiert. Besuchen Sie http://www.adventuresinsoftware.com/generics/ und klicken Sie auf „Tupel“ -Link.
Andere Tipps
Builtin Klassen
In bestimmten Fällen bereits das .NET Framework bietet Tupel-ähnlichen Klassen, die Sie in der Lage sein können, nutzen.
Pairs und Triples
Die allgemeine System.Collections.Generic.KeyValuePair Klasse könnte als Ad-hoc-Paar-Implementierung verwendet werden. Dies ist die Klasse, die das generic Wörterbuch intern verwendet.
Alternativ können Sie in der Lage sein, mit dem auszukommen System.Collections.DictionaryEntry Struktur, die als ein rudimentäres Paar wirkt und hat den Vorteil, wobei in mscorlib verfügbar. aber auf der anderen Seite, ist, dass diese Struktur ist nicht stark typisierte.
Paare und Triples sind auch in Form der zur Verfügung stehenden System.Web.UI.Pair und System.Web.UI.Triplet Klassen. Obwohl Thesen Klassen leben in der System.Web Montage sie könnten perfekt geeignet für WinForms Entwicklung sein. Allerdings sind diese Klassen sind nicht stark entweder eingegeben und nicht geeignet in einigen Szenarien sein könnte, wie ein allgemeinen purposed Rahmen oder Bibliothek.
höhere Ordnung Tupeln
Bei einer höheren Ordnung Tupeln, kurz der eigene Klasse rollt, kann es keine einfache Lösung.
Wenn Sie installiert haben die F # -Sprache , könnten Sie die Referenz FSharp.Core.dll das enthält eine Reihe von allgemeinen unveränderlich Microsoft.Fsharp.Core.Tuple Klassen bis zu generic Sextupel. Aber auch wenn ein nicht modifiziertes FSharp.Code.dll wird neu verteilt, ist F # eine Forschung Sprache und ein work in progress so Diese Lösung ist wahrscheinlich von Interesse in akademischen Kreisen nur sein.
Wenn Sie nicht über Ihre eigene Klasse erstellen und unbequem Referenzierung könnte den F # -Bibliothek, ein raffinierter Trick besteht die allgemeine KeyValuePair-Klasse in erstreckt, so dass der Wert Mitglied eine verschachtelte KeyValuePair selbst ist.
Zum Beispiel zeigt der folgende Code, wie Sie das nutzen könnten KeyValuePair um eine Triples zu erstellen:
int id = 33;
string description = "This is a custom solution";
DateTime created = DateTime.Now;
KeyValuePair<int, KeyValuePair<string, DateTime>> triple =
new KeyValuePair<int, KeyValuePair<string, DateTime>>();
triple.Key = id;
triple.Value.Key = description;
triple.Value.Value = created;
Dies ermöglicht es, die Klasse zu jeder beliebigen Ebene zu erstrecken, wie erforderlich ist.
KeyValuePair<KeyValuePair<KeyValuePair<string, string>, string>, string> quadruple =
new KeyValuePair<KeyValuePair<KeyValuePair<string, string>, string>, string>();
KeyValuePair<KeyValuePair<KeyValuePair<KeyValuePair<string, string>, string>, string>, string> quintuple =
new KeyValuePair<KeyValuePair<KeyValuePair<KeyValuePair<string, string>, string>, string>, string>();
Ihre eigene Rolle
In anderen Fällen müssen Sie rollen Sie Ihre eigenen greifen Tupel-Klasse, und dies ist nicht schwer.
können Sie erstellen einfache Strukturen wie folgt:
struct Pair<T, R>
{
private T first_;
private R second_;
public T First
{
get { return first_; }
set { first_ = value; }
}
public R Second
{
get { return second_; }
set { second_ = value; }
}
}
Frameworks und Bibliotheken
Dieses Problem wurde vor und allgemeine Rahmenbedingungen in Angriff genommen existieren. Unten ist ein Link zu einem solchen Rahmen:
public struct Pair<T1, T2>
{
public T1 First;
public T2 Second;
}
public struct Triple<T1, T2, T3>
{
public T1 First;
public T2 Second;
public T3 Third;
}
Schneller Vorlauf bis 2010, unterstützt .NET 4.0 jetzt n-Tupel von beliebigen n . Diese Tupel implementieren strukturelle Gleichheit und Vergleich wie erwartet.
ich in der Regel nur meine eigene Struktur erstellen, die Werte enthalten. Es ist oft ein bisschen besser lesbar;)
KeyValuePair ist die beste Klasse zu erweitern, wenn Sie nicht wollen, Ihre eigenen Klassen erstellen.
int id = 33;
string description = "This is a custom solution";
DateTime created = DateTime.Now;
KeyValuePair<int, KeyValuePair<string, DateTime>> triple =
new KeyValuePair<int, KeyValuePair<string, DateTime>>();
triple.Key = id;
triple.Value.Key = description;
triple.Value.Value = created;
Sie können es auf so vielen Ebenen erstrecken, wie Sie wollen.
KeyValuePair<KeyValuePair<KeyValuePair<string, string>, string, string> quadruple =
new KeyValuePair<KeyValuePair<KeyValuePair<string, string>, string, string>();
Hinweis : Die Klassen Triplet und Paar existiert innerhalb der System.Web -dll, so ist es nicht sehr geeignet für andere Lösungen als ASP.NET.
Sie können relativ leicht Ihre eigenen Tupel Klassen erstellen, das einzige, was potentiell chaotisch erhält, ist Ihre Gleichheit und hashcode Überschreibungen (wichtig, wenn Sie vorhaben, sie in Wörterbüchern verwenden).
Es ist zu beachten, dass .Net eigene Eine einfache Lösung ist nicht noch erwähnt. Sie können auch nur einen KeyValuePair<TKey,TValue>
Struktur hat
List<T>
verwenden. Es ist eingebaut, effizient und einfach zu bedienen. Zugegeben, es zunächst ein wenig seltsam aussieht, aber es macht seinen Job perfekt, vor allem für eine größere Anzahl der Elemente.
NGenerics - die beliebte .Net Algorithmen und Datenstrukturen Bibliothek, hat vor kurzem eingeführt unveränderlich Datenstrukturen auf den Satz.
Die ersten unveränderlich diejenigen waren zu implementieren Paar und Tupel Klassen. Der Code ist mit Tests abgedeckt und ist sehr elegant. Sie können es hier . Sie arbeiten an den anderen unveränderlichen Alternativen im Moment, und sie sollte in Kürze fertig sein.
Es gibt nicht in gebaut, aber ein Paar
Ja, es ist System.Web.UI.Pair und System.Web.UI.Triplet (die einen überladenen Schöpfer für Pair-Verhalten hat!)
Für den ersten Fall, ich in der Regel verwenden
Dictionary<KeyValuePair<string, int>, object>
Es gibt keine integrierten Klassen dafür. Sie können KeyValuePair oder eine eigene Implementierung ausrollen.
Sie könnten System.Collections.Generic.KeyValuePair als Pair-Implementierung verwenden.
Oder Sie könnten nur Ihre eigenen implementieren, sie sind nicht schwer:
public class Triple<T, U, V>
{
public T First {get;set;}
public U Second {get;set;}
public V Third {get;set;}
}
Natürlich können Sie einen Tag auf ein Problem stoßen, die Triple-(String, int, int) nicht kompatibel mit Triple ist (int, int, string). Vielleicht statt mit System.Xml.Linq.XElement gehen.
Es gibt auch die Tuple <> Typen in F #; Sie müssen nur FSharp.Core.dll verweisen.