Was ist der kürzeste Weg, um eine unveränderbare Klasse in C # zu erstellen?

8

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?

    
ChaseMedallion 07.03.2013, 22:33
quelle

3 Antworten

4

Sie könnten automatische Eigenschaften mit privaten Sätzen verwenden

%Vor%     
Phil Patterson 07.03.2013 22:42
quelle
1

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.

%Vor%

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:

  • zur Konstruktionszeit pre-compute 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.
  • Verstecke generische Namen (zB protected oder verstecke dich einfach vor Intellisence mit EditorBrowsableAttribute ), so dass es keine Verwirrung über zwei Namen gibt.
  • erwäge, Feldtypen zu erzwingen, die in Debug-Builds / FxCop-Regeln ...
  • unveränderlich sind

Randnotiz: Sehen Sie sich Eric Lipperts Serie über unveränderliche Arten .

    
Alexei Levenkov 07.03.2013 22:41
quelle
1

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.

    
supercat 12.03.2013 17:14
quelle

Tags und Links