Bei veränderlichen Typen ist der Unterschied im Verhalten zwischen Wert und Referenztypen klar:
%Vor%Bei unveränderlichen Typen ist dieser Unterschied jedoch weniger eindeutig:
%Vor% Unveränderbare Referenztypen verwenden häufig auch Wertesemantiken (z. B. das kanonische Beispiel System.String
):
Eric Lippert hat bereits auf seinem Blog diskutiert (zB hier ), dass die Tatsache, dass Werttypen häufig (wenn dies für diese Diskussion nicht wirklich wichtig ist) auf dem Stack zugewiesen wird, ein Implementierungsdetail ist und dass es im Allgemeinen nicht vorschreiben sollte, ob Sie ein Objekt einen Wert oder Referenztyp.
Angesichts dieser verschwommenen Unterscheidung im Verhalten für unveränderliche Typen, welche Kriterien lässt dies für uns übrig, um zu entscheiden, ob ein unveränderlicher Typ ein Referenztyp oder ein Werttyp sein soll?
Sollen unveränderliche Typen mit der unveränderlichen Betonung von Werten gegen Variablen immer Wertsemantik implementieren?
Ich würde sagen, dass Erics Blog-Post Sie Link gibt Ihnen genau die Antwort:
Ich bedauere, dass die Dokumentation funktioniert nicht auf das konzentrieren, was am relevantesten ist; durch Fokussierung auf ein weitgehend irrelevantes Implementierung Detail, wir vergrößern die Wichtigkeit dieser Implementierung Detail und verschleiern die Bedeutung von was einen Werttyp semantisch macht sinnvoll. Ich wünsche das allen sehr Artikel erklären was "der Stapel" Es wäre stattdessen Zeit zu erklären was genau "nach Wert kopiert" bedeutet und wie Missverständnis oder Missbrauch "Kopie nach Wert" kann Fehler verursachen.
Wenn Ihre Objekte eine "copy-by-value" Semantik haben sollen, dann machen Sie Werttypen. Wenn sie eine "copy-by-reference" -Semantik haben sollen, machen Sie sie zu Referenztypen.
Er sagt auch das, womit ich einverstanden bin:
Ich würde immer die Wahl des Werts treffen Typ vs Referenztyp basierend auf ob der Typ semantisch ist einen Wert darstellen oder semantisch a Verweis auf etwas.
.NET Art von Hinweisen auf eine Antwort mit der String
-Klasse. Es ist unveränderlich, aber es ist ein Referenztyp. Machen Sie Ihren unveränderlichen Typ act so viel wie möglich zu einem Werttyp. Es spielt keine Rolle, ob es sich tatsächlich um einen Werttyp handelt.
Das einzige Kriterium, das mir einfällt, ist: Wenn das Kopieren teuer ist (ein String
könnte viel kopieren!), machen Sie es zu einem Referenztyp. Wenn es schnell kopiert werden soll, wählen Sie einen Werttyp. Bedenken Sie auch, wenn Sie Referenzen vergleichen müssen - das ist wahrscheinlich der einzige schwierige Teil mit unveränderlichen Referenztypen.
Es gibt eine wichtige Kategorie von unveränderlichen Typen (über die Eric Lippert ausführlich berichtet hat), die als Reverenz-Typen implementiert werden müssen: rekursive Typen wie Listenknoten, Baumknoten und dergleichen. Werttypen können keine zyklischen Definitionen haben, wie dies beispielsweise bei einem verknüpften Listenknoten der Fall ist:
%Vor%Tags und Links .net c# immutability