Ich finde, ich muss viele unveränderliche Klassen erstellen, und ich würde gerne einen Weg finden, dies ohne redundante Informationen zu tun. Ich kann keinen anonymen Typ verwenden, da ich diese Klassen von Methoden zurückgeben muss. Ich möchte Intellisense-Unterstützung, daher möchte ich keine Wörterbücher, dynamische oder ähnliche verwenden. Ich möchte auch gut benannte Eigenschaften, die Tuple & lt; & gt; ausschließen. Bisher habe ich einige Muster ausprobiert:
%Vor%Diese beiden sind etwas weniger ausführlich als das "Standard" -Muster zum Erstellen von schreibgeschützten Feldern, setzen diese über einen Konstruktor und setzen sie über Eigenschaften frei. Beide Methoden haben jedoch immer noch viele überflüssige Standardwerte.
Irgendwelche Ideen?
Sie könnten automatische Eigenschaften mit privaten Sätzen verwenden
%Vor% Sehen Sie, ob public {get;private set;}
Eigenschaften für Ihren Fall funktionieren - ein bisschen kompakter als eine separate Felddeklaration, genau die gleiche Semantik.
Update: Während ChaseMedallion in der Frage kommentierte und inline ging, bietet dieser Ansatz nicht automatisch generierte GetHashCode
und Equals
Methoden im Gegensatz zu Tuple
approach.
Ich mag Tuple
approach, da es ein Objekt gibt, das sicher in interessanten Kontexten verwendet werden kann und nette Namen liefert. Wenn ich viele Arten dieser Art erstellen müsste, würde ich in Erwägung ziehen, Tuple
classes erneut zu implementieren:
GetHashCode
und als Teil des Objekts speichern, um unbeschränkte Prüfungen auf Sammlungen / Strings zu vermeiden. Möglicherweise optional, um Fälle zuzulassen, die häufig als Schlüssel in Dictionary
verwendet werden. protected
oder verstecke dich einfach vor Intellisence mit EditorBrowsableAttribute ), so dass es keine Verwirrung über zwei Namen gibt. Randnotiz: Sehen Sie sich Eric Lipperts Serie über unveränderliche Arten .
Unveränderbare Klassen sind am nützlichsten, wenn eine entsprechende veränderbare Klasse existiert, deren Inhalte leicht von einer unveränderlichen Instanz geladen oder in eine neue unveränderliche Instanz kopiert werden können. Wenn ein unveränderliches Objekt mehr als 2-3 "Änderungen" an ihm vornehmen muss (dh die Referenz so ändern muss, dass es auf ein unveränderliches Objekt zeigt, das sich vom Original unterscheidet), werden die Daten in ein veränderbares Objekt kopiert und geändert. und das Zurückspeichern ist oft praktischer als das Erstellen eines Objekts, das sich vom Original auf eine Art unterscheidet, dann das Erzeugen eines neuen Objekts, das sich von dem auf eine andere Weise unterscheidet, usw.
Ein einfacher verallgemeinerter Ansatz besteht darin, einen (möglicherweise internen) exposed-field-Strukturtyp zu definieren, und dann haben sowohl die veränderbare als auch die unveränderliche Klasse ein Feld dieses Typs. Die Accessor-Eigenschaften müssten für beide Klassen getrennt definiert werden, aber die beiden Methoden GetHashCode
und Equals
der Methoden könnten mit den entsprechenden Methoden der zugrunde liegenden Struktur verknüpft sein. Das Erstellen einer Instanz eines der beiden Typen mit einer Instanz des anderen Typs kann mithilfe einer einzelnen Strukturzuweisung erfolgen, anstatt alle Elemente einzeln kopieren zu müssen.
Wenn jemandes Programmierer verstehen, wie Strukturen funktionieren (ich würde dieses Wissen als fundamental betrachten, selbst wenn andere nicht zustimmen), könnte man den Strukturtyp öffentlich machen. Eine Mutable-Holder-Klasse kann auch dann nützlich sein, wenn die Struktur öffentlich ist, da es Situationen gibt, in denen Referenzsemantik nützlich ist (zB möchte man etwas in Dictionary
ändern können, ohne die Dictionary
selbst ändern zu müssen) ), aber das convert-to-mutable / change / convert-to-immutable-Muster funktioniert sogar noch besser mit Strukturtypen als mit Klassentypen.
Tags und Links c# immutability tuples