Frage

Ich arbeite eine unveränderliche Klasse zum Erstellen.
Ich habe alle Eigenschaften als schreibgeschützt gekennzeichnet.

Ich habe eine Liste der Elemente in der Klasse.
Obwohl, wenn die Eigenschaft schreibgeschützt ist die Liste kann geändert werden.

Das Aussetzen der IEnumerable der Liste macht es unveränderlich.
Ich wollte wissen, was die Grundregeln ist ein eine Klasse unveränderlich zu folgen hat zu machen?

War es hilfreich?

Lösung

Ich glaube, Sie auf dem richtigen Weg sind -

  • alle Informationen in der Klasse injiziert sollte im Konstruktor geliefert werden
  • alle Eigenschaften sollten nur sein Getter
  • , wenn eine Sammlung (oder Array) in den Konstruktor übergeben wird, sollte es kopiert werden, um den Anrufer zu verhindern, es später zu modifizieren
  • wenn du gehst, um Ihre Sammlung zurückkehren, entweder Rückkehr eine Kopie oder eine schreibgeschützte Version (zum Beispiel mit ArrayList.ReadOnly oder ähnlich - Sie können mit dem vorherigen Punkt kombinieren diese und speichern ein Read-Only werden zurück kopieren wenn Anrufer es) zugreifen, Rückkehr einen Enumerator oder eine andere Methode / Eigenschaft verwenden, die nur für den Lesezugriff in die Sammlung ermöglicht
  • bedenken Sie, dass Sie immer noch das Aussehen eines wandelbaren Klasse haben können, wenn alle Ihre Mitglieder wandelbar sind - wenn dies der Fall ist, sollten Sie kopieren weg, was Staat wollen Sie beibehalten und vermeiden gesamten veränderbare Objekte zurückkehren, es sei denn, Sie kopieren Sie sie, bevor sie zurück an den Anrufer zu geben - ein weitere Option ist nur unveränderlich „Abschnitte“ des veränderlichen Objekts zurück - dank @ Brian Rasmussen mich für die Förderung dieses Punkt
  • erweitern

Andere Tipps

Um unveränderlich zu sein, alle Ihre Eigenschaften und Felder sollten nur lesbar sein. Und die Elemente in jeder Liste sollte sich unveränderlich sein.

Sie können eine Nur-Lese-Liste Eigenschaft machen, wie folgt:

public class MyClass
{
    public MyClass(..., IList<MyType> items)
    {
        ...
        _myReadOnlyList = new List<MyType>(items).AsReadOnly();
    }

    public IList<MyType> MyReadOnlyList
    {
        get { return _myReadOnlyList; }
    }
    private IList<MyType> _myReadOnlyList

}

Auch beachten Sie, dass:

public readonly object[] MyObjects;

ist nicht unveränderlich, auch wenn es mit Nur-Lese-Schlüsselwort gekennzeichnet ist. Sie können immer noch einzelne Array-Referenzen / Werte von Index-Accessor geändert werden.

Mit der ReadOnlyCollection Klasse. Es liegt in der System.Collections.ObjectModel Namespace.

Auf alles, was Ihre Liste zurückgibt (oder im Konstruktor), stellen die Liste als Nur-Lese-Sammlung.

using System.Collections.ObjectModel;

...

public MyClass(..., List<ListItemType> theList, ...)
{
    ...
    this.myListItemCollection= theList.AsReadOnly();
    ...
}

public ReadOnlyCollection<ListItemType> ListItems
{
     get { return this.myListItemCollection; }
}

Eine andere Möglichkeit wäre, ein Besuchermuster zu verwenden, anstatt alle internen Sammlungen an allen auszusetzen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top