Domanda

Giuro che ho visto un esempio di questo, ma sono stato googling per un po 'e non riesco a trovarlo.

Ho una classe che ha un riferimento a un oggetto e la necessità di avere un GET; Metodo per esso. Il mio problema è che io non voglio che nessuno sia in grado di giocherellare con esso, vale a dire che voglio loro di ottenere una versione di sola lettura di esso, (nota che ho bisogno di essere in grado di modificare dall'interno mia classe).

Grazie

È stato utile?

Soluzione

No, non c'è modo di fare questo. Per esempio, se si torna un List<string> (e non è immutabile), allora i chiamanti essere in grado di aggiungere voci.

Il modo normale giro questo è per restituire un involucro immutabile, ad esempio ReadOnlyCollection<T> .

Per altri tipi mutabili, potrebbe essere necessario clonare il valore prima di restituirlo.

Si noti che solo restituendo una vista interfaccia immutabile (ad esempio ritornando IEnumerable<T> anziché List<T>) non si fermerà un chiamante dalla fusione nel tipo mutabile e mutazione.

EDIT: Si noti che, a parte ogni altra cosa, questo tipo di preoccupazione è una delle ragioni per le quali tipi immutabili rendono più facile ragionare sul codice:)

Altri suggerimenti

restituire un riferimento a un'interfaccia stripped-down:

 interface IFoo
   string Bar { get; }

 class ClassWithGet
   public IFoo GetFoo(...);

Questo non è possibile. Accesso get e set per fare riferimento a tipi ottenere e impostare il riferimento all'oggetto. È possibile impedire modifiche al riferimento utilizzando un setter privata (o interno), ma non si può impedire che le modifiche all'oggetto in sé se è esposto da un getter.

Se l'oggetto non è troppo complicato / estesa poi scrivere un wrapper attorno ad esso.

Ad esempio:

class A {
    public string strField = 'string';
    public int intField = 10;
}

class AWrapper {
    private A _aObj;

    public AWrapper(A aobj) {
      _aObj = A;
    }

    public string strField {
         get {
            return _aObj.strField;
         }
    }

    public int intField {
         get {
            return _aObj.intField;
         }
    }
}

Così ora tutto ciò che fai è dare il vostro codice client un'istanza della classe AWrapper in modo che essi possono utilizzare solo ciò che si consente loro di vedere.

questo può diventare un po 'complicato e potrebbe non scala bene se la classe base non è scolpito nella pietra, ma per la maggior parte situazione semplice possa solo fare il trucco. Credo che questo si chiama un modello di facciata (ma non citare me su quel =))

La tua domanda si legge come siete alla ricerca di:

public PropertyName { get; private set; }

Ma poi, dato le risposte finora non sono sicuro di interpretare la sua domanda. Inoltre, chi sono io per dubbio Jon Skeet? :)

Sono d'accordo con ReadOnlyCollection

Vedere il mio semplice codice:

 private List<Device> _devices;
public readonly System.Collections.ObjectModel.ReadOnlyCollection<Device> Devices 
{
 get
 { 
return (_devices.AsReadOnly());
 } 

}

ReadOnlyCollection dosen't ha Aggiungi metodo in modo utente non posso aggiungere oggetti da it.But ther è alcuna garanzia che se l'utente può modificare gli oggetti chiamando i loro metodi ....

Ho affrontato questo problema in un certo modo. Ho una classe CategoryViewModel, che hanno una categoria di proprietà che voglio privato di sola lettura:

public CategoryViewModel
{
    private Category { get; }

}

In realtà, io voglio che sia esportato in sola lettura per altra classe. Tuttavia non posso fare una cosa simile. Nel mio caso (forse aiuterà alcuni altri ragazzi), voglio aggiungere che a un repository. L'unico modo che ho trovato è quello di avere una funzione con il repository come param 1, ed un'azione come param 2:

public void ApplyAction(ICategoryRepository repo, Action<ICategoryRepository, Category> action)
{
    action(repo, Category);
}

Come quella, da qualche altra parte, non posso fare una cosa:

 categoryViewModel.ApplyAction(_repository, (r, c) => r.MarkForInsertOrUpdate(c));

Questo può aiutare gli altri ad esporre lì proprietà solo per certains casi e in grado di gestire.

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