Oft möchten Sie mehrere Werte senden, aber aufgrund der geringen Verwendung (d. H. Es wird nur an ein oder zwei Stellen verwendet), ist es schwer zu rechtfertigen, einen neuen Typ zu erstellen. Die Tuple<...>
und KeyValuePair<,>
Art sind sehr nützlich, aber es gibt keine echte Sprachunterstützung für sie.Gibt es Tipps, um das Arbeiten mit Tupel in C# zu erleichtern?
Nun, ein guter Trick für Listen von Tupeln ist es, einen Typ zu erstellen, der die Liste erweitert und eine benutzerdefinierte Add-Methode hinzufügt: z.
public class TupleList<T1,T2> : List<Tuple<T1,T2>>{
public void Add(T1 key, T2 value){
base.Add(Tuple.Create(key, value));
}
}
Das bedeutet, dass, wenn ich eine Methode, die eine IEnumerable<Tuple<int,string>>
nimmt, habe ich den folgenden Code schnell die Liste aufbauen verwenden können, um wie so ::
Foo(new TupleList<int,string>{{1,"one"},{2,"two"},{3,"three"}});
Dies macht Werte in ein Tupel Wicklung Liste einfacher, da wir nicht ständig Tuple.Create
sagen müssen, und uns fast zu einer netten funktionalen Sprachensyntax bringt.
Wenn Sie jedoch mit einem Tupel arbeiten, ist es nützlich, es in seine verschiedenen Komponenten zu zerlegen. Diese Erweiterungsmethode könnte nützlich sein, in dieser Hinsicht ::
public static void Unwind<T1,T2>(this Tuple<T1,T2> tuple,out T1 var1,out T2 var2)
{
var1 = tuple.Item1;
var2 = tuple.Item2;
}
Aber auch das ist ärgerlich, da out-Parameter überhaupt nicht Variante sind. Das heißt, wenn T1 eine Zeichenkette ist, kann ich keine Objektvariable einsenden, obwohl sie zuweisbar ist, wenn ich die Abwicklung ansonsten von Hand erledigen kann. Ich kann nicht wirklich einen Grund vorschlagen, warum Sie diese Abweichung wollen, aber wenn es dort ist, kann ich nicht sehen, warum Sie es verlieren möchten.
Hat jemand andere Tipps, um in C# funktionierende Tupel oder tupelartige Objekte einfacher zu machen?
Eine wichtige potenzielle Verwendung für Tupel könnte generische Memoisierung sein. Das ist sehr einfach in Sprachen wie F #, aber schwer in C#.
Ich verwende derzeit Tuples, um eine MethodBase und ein Array von Token (Konstanten, Objekte oder Argumenttoken) bereitzustellen, die einem dynamisch erstellten Objekt zur Verfügung gestellt werden, um bestimmte Elementfelder zu erstellen.
Da ich die Syntax für API-Konsumenten einfacher machen wollte, habe ich Add-Methoden erstellt, die ein ConstructorInfo
oder ein MethodInfo
und ein params Array von Objekten übernehmen können.
Edit: Eric Lippert wie üblich eine hervorragende Motivation für hier Tupeln mit und er sagt auch, was ich vermutete es wirklich keine Unterstützung ist: What requirement was the tuple designed to solve?
Können Sie uns Ihren Anwendungsfall zeigen, in dem Sie es vorziehen, Parameter des Typs 'Objekt' anstelle von Variablen einzugeben, die tatsächlich eingegeben wurden? Zeigen Sie uns, wie Sie mit ein bisschen Kontext "Abwickeln" nennen möchten. –
out-Parameter sind starr, weshalb sie nicht als die Wahl zur Wahl vorgeschlagen werden. Ich würde für API-Unterstützung wie F # töten, die Parameter in Tupel ausgibt. –
Komposition über Vererbung! – Eric