Domanda

Sto lavorando per creare una classe immutabile.
Ho contrassegnato tutte le proprietà come di sola lettura.

Ho un elenco di elementi nella classe.
Sebbene se la proprietà è di sola lettura, l'elenco può essere modificato.

Esporre l'IEnumerable dell'elenco lo rende immutabile.
Volevo sapere quali sono le regole di base che uno deve seguire per rendere immutabile una classe?

È stato utile?

Soluzione

Penso che tu sia sulla buona strada -

  • tutte le informazioni immesse nella classe devono essere fornite nel costruttore
  • tutte le proprietà dovrebbero essere solo getter
  • se una raccolta (o matrice) viene passata al costruttore, dovrebbe essere copiata per impedire al chiamante di modificarla in seguito
  • se hai intenzione di restituire la tua raccolta, restituisci una copia o una versione di sola lettura (ad esempio, utilizzando ArrayList.ReadOnly o simile - puoi combinarlo con il punto precedente e conservare una copia di sola lettura da restituire quando i chiamanti accedono ad esso), restituiscono un enumeratore o usano altri metodi / proprietà che consentono l'accesso in sola lettura alla raccolta
  • tieni presente che potresti avere l'aspetto di una classe mutabile se uno qualsiasi dei tuoi membri è mutabile - in tal caso, dovresti copiare qualsiasi stato desideri conservare ed evitare di restituire interi oggetti mutabili, a meno che li copi prima di restituirli al chiamante - un'altra opzione è quella di restituire solo " sezioni " dell'oggetto mutevole - grazie a @Brian Rasmussen per avermi incoraggiato ad espandere questo punto

Altri suggerimenti

Per essere immutabili, tutte le proprietà e i campi devono essere di sola lettura. E gli elementi in qualsiasi elenco dovrebbero essere essi stessi immutabili.

Puoi creare una proprietà dell'elenco di sola lettura come segue:

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

}

Inoltre, tieni presente che:

public readonly object[] MyObjects;

non è immutabile anche se è contrassegnato da una sola parola chiave. Puoi comunque modificare i singoli riferimenti / valori dell'array tramite l'accesso all'indice.

Utilizza la classe ReadOnlyCollection. Si trova nello System.Collections.ObjectModel spazio dei nomi.

Su tutto ciò che restituisce il tuo elenco (o nel costruttore), imposta l'elenco come raccolta di sola lettura.

using System.Collections.ObjectModel;

...

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

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

Un'altra opzione sarebbe quella di utilizzare un modello visitatore invece di esporre tutte le raccolte interne.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top