Ich möchte zunächst erwähnen, dass C # bereits Unterstützung für anonyme Typen hatte . Welches sind Referenztypen. Sie hatten also bereits eine geeignete Alternative zum Erstellen einer benannten Klasse.
Ein Vorteil einer benannten Klasse besteht darin, dass sie leichter wiederverwendet werden kann (z. B. wenn Sie denselben Typ an mehreren Stellen benötigen) und dokumentiert. Da der anonyme Typ anonym ist, können Sie nur dann Variablen eingeben, wenn Sie ihn verwenden können. Dies var
schränkt die Kontexte ein, in denen anonyme Typen nützlich sind (z. B. können Sie sie nicht als Feldtypen, Rückgabetypen oder Parametertypen verwenden). .
Natürlich können Sie einige der Einschränkungen anonymer Typen mit verwenden System.Tuple
. Dies ist auch ein Referenztyp, den Sie explizit verwenden können. Der Nachteil ist, dass es keine benutzerdefinierten Namen für die Mitglieder gibt.
C # 7-Tupel ( ValueTuple
) können als ähnlich wie anonyme Typen angesehen werden. Der erste Unterschied besteht darin, dass es sich um Werttypen handelt. Dies bedeutet, dass diese Tupel einen Leistungsvorteil haben, solange sie sich im lokalen Bereich befinden oder sich über den Stapel bewegen (was aufgrund seiner Einschränkung die übliche Verwendung anonymer Typen ist).
Der zweite Unterschied besteht darin, dass die neue Syntax ermöglicht, dass Tupel an mehr Stellen als anonyme Typen angezeigt werden. Wie Sie wissen, haben Sie syntaktischen Zucker, um den Rückgabetyp zu definieren ValueTuple
(während Sie anonyme Typen verwenden, die Sie zurückgeben mussten object
).
Der dritte Unterschied besteht darin, dass die ValueTuple
sofortige Dekonstruktion unterstützt wird. So zitieren Sie die Neuerungen in C # 7.0 :
Eine andere Möglichkeit, Tupel zu konsumieren, besteht darin, sie zu dekonstruieren. Eine dekonstruierende Deklaration ist eine Syntax zum Aufteilen eines Tupels (oder eines anderen Werts) in seine Teile und zum individuellen Zuweisen dieser Teile zu neuen Variablen:
(string first, string middle, string last) = LookupName(id1);
WriteLine($"found {first} {last}.");
Dies können Sie auch mit benutzerdefinierten Typen tun, indem Sie eine Deconstruct-Methode hinzufügen .
Für Zusammenfassung:
ValueTuple
hat syntaktischen Zucker in C # 7.0, der für die Lesbarkeit berücksichtigt werden sollte.
ValueTuple
ist ein Werttyp. Alle Vor- und Nachteile zwischen der Verwendung von a class
und a struct
gelten.
ValueTuple
kann explizit verwendet werden (mit oder ohne syntaktischen Zucker), so dass es die Vielseitigkeit hat, System.Tuple
während benannte Mitglieder erhalten bleiben .
ValueTuple
unterstützt die Dekonstruktion.
Angesichts der Tatsache, dass es sich bei dem Muss um syntaktischen Zucker handelt, würde ich sagen, dass das stärkere Argument für die Wahl ValueTuple
dasselbe Argument für die Wahl von a ist struct
. Das wäre ideal für kleine, unveränderliche Typen, die meistens auf dem Stapel leben (so dass Sie nicht viel Boxen und Unboxen haben).
Im Vergleich zu ValueTuple
einer vollständigen Struktur würde ich unter Berücksichtigung des syntaktischen Zuckers empfehlen, diese ValueTuple
standardmäßig zu verwenden, es sei denn, Sie benötigen ein explizites Layout oder müssen Methoden hinzufügen.
Ich möchte auch sagen, dass der syntaktische Zucker die Lesbarkeit nicht unbedingt verbessert. Der Hauptgrund ist, dass Sie den Typ nicht benennen und der Name des Typs dem Code eine Bedeutung verleiht. Darüber hinaus können Sie einer struct
oder einer class
Erklärung eine Dokumentation hinzufügen , die das Verständnis erleichtert.
Alles in allem gibt die Situation, in der ValueTuple
wirklich glänzt, mehrere Werte von einer Methode zurück. In diesem Fall müssen keine neuen out
Parameter erstellt werden. Und die Dokumentation der ValueTuple
verwendeten kann in der Dokumentation der Methode leben. Wenn Sie feststellen, dass Sie etwas anderes mit dem tun müssen ValueTuple
(z. B. das Definieren von Erweiterungsmethoden), würde ich empfehlen, stattdessen einen benannten Typ zu erstellen.