Domanda

Possibile Duplicare:
Perché sono modificabili le strutture del male?

L'ho letto in un sacco di posti, anche qui che è meglio fare le strutture come immutabile.

Qual è la ragione dietro a questo?Vedo un sacco di Microsoft-creato strutture che sono mutabili, come quelli in xna.Probabilmente ci sono molti di più nel BCL.

Quali sono i pro e i contro di queste linee guida?

È stato utile?

Soluzione

Le strutture devono rappresentare valori . I valori non cambiano. Il numero 12 è eterno.

Tuttavia, considera:

Foo foo = new Foo(); // a mutable struct
foo.Bar = 27;
Foo foo2 = foo;
foo2.Bar = 55;

Ora foo.Bar e foo2.Bar sono diversi, il che è spesso inaspettato. Soprattutto negli scenari come le proprietà (per fortuna il compilatore lo rileva). Ma anche collezioni ecc .; come mai li mutate sensibilmente?

La perdita di dati è fin troppo facile con le strutture mutabili.

Altri suggerimenti

Il grande svantaggio è che le cose non si comportano come ci si aspetta da loro, in particolare se la mutabilità proviene da una miscela del valore diretto e di un tipo di riferimento al suo interno.

Ad essere sincero, non riesco a ricordare dalla parte superiore della mia testa tutti gli strani problemi che ho visto le persone emergere nei newsgroup quando hanno usato strutture mutabili - ma quelle ragioni certamente esistono. Le strutture mutabili causano problemi. Stai lontano.

EDIT: ho appena trovato un'email che ho scritto poco fa su questo argomento. Elabora solo un po ':

  • È filosoficamente sbagliato: una struttura dovrebbe rappresentare una sorta di valore fondamentale. Sono sostanzialmente immutabili. Non puoi cambiare il numero 5. Puoi cambiare il valore di una variabile da 5 a 6, ma logicamente non puoi cambiare il valore stesso.

  • È praticamente un problema: crea molte situazioni strane. È particolarmente negativo se è modificabile tramite un'interfaccia. Quindi puoi iniziare a cambiare i valori in scatola. Ick. Ho visto molti post di newsgroup dovuti a persone che cercavano di usare strutture mutabili e che si imbattevano in problemi. Ho visto un esempio LINQ molto strano che non funzionava perché List<T>.Enumerator è una struttura, ad esempio.

Nel mio progetto (critico per le prestazioni) uso spesso strutture mutabili e non incontro problemi, perché comprendo le implicazioni della semantica della copia. Per quanto ne so, la ragione principale per cui le persone sostengono strutture immutabili è che le persone che non comprendono le implicazioni non possono mettersi nei guai.

Non è una cosa così terribile - ma ora siamo in pericolo che diventi " la verità evangelica " ;, quando in realtà ci sono momenti in cui è legittimamente la migliore opzione per fare un strutt mutabile. Come per tutte le cose, ci sono eccezioni alla regola.

Non c'è niente di più economico da manipolare di una struttura mutabile, motivo per cui spesso lo vedi in codice ad alte prestazioni come le routine di elaborazione grafica.

Sfortunatamente le strutture mutabili non giocano bene con oggetti e proprietà, è troppo facile modificare una copia di una struttura invece della struttura stessa. Pertanto, non sono appropriati per la maggior parte del codice.

P.S. Per evitare il costo della copia di strutture mutabili, di solito vengono archiviate e passate in array.

Il motivo tecnico è che le strutture mutabili appaiono per poter fare cose che in realtà non fanno. Poiché la semantica in fase di progettazione è uguale ai tipi di riferimento, questo diventa fonte di confusione per gli sviluppatori. Questo codice:

public void DoSomething(MySomething something)
{
    something.Property = 10;
}

Si comporta in modo abbastanza diverso a seconda che MySomething sia struct o class. Per me, questo è un motivo convincente, ma non più convincente. Se guardi DDD 's Oggetto valore , puoi vedere la connessione a come le strutture dovrebbero essere trattate. Un oggetto valore in DDD può essere rappresentato al meglio come tipo di valore in .Net (e quindi una struttura). Perché non ha identità, non può cambiare.

Pensa a questo in termini di qualcosa come il tuo indirizzo. Puoi & Quot; cambiare & Quot; il tuo indirizzo, ma l'indirizzo stesso non è cambiato. In effetti, ti è stato assegnato un nuovo indirizzo. Concettualmente, funziona, perché se in realtà hai cambiato il tuo indirizzo, anche i tuoi coinquilini dovrebbero spostarsi.

Hai chiesto i pro e i contro di non seguendo le linee guida secondo cui le strutture dovrebbero essere immutabili.

Contro: I contro sono ben coperti nelle risposte esistenti e la maggior parte dei problemi descritti sono dovuti alla stessa causa - comportamento imprevisto dovuto alla semantica del valore delle strutture .

Pro: Il pro principale dell'uso di strutture mutabili può essere rendimento . Ovviamente, questo consiglio viene fornito con tutti i soliti avvertimenti sulle ottimizzazioni: assicurati che parte del tuo codice abbia bisogno di per essere ottimizzato e assicurati che eventuali modifiche ottimizzino effettivamente le prestazioni del tuo codice tramite la profilazione.

Per un eccellente articolo che discute quando potresti voler usare strutture mutabili, vedi Performance Quiz on Value-based Programming (o più specificamente, le risposte ).

Una struttura generalmente dovrebbe rappresentare una singola unità di qualche tipo.Come tale, non ha molto senso cambiare una delle proprietà del valore, ha più senso creare un nuovo valore se si desidera un valore che è diverso in qualche modo.

La semantica diventa più semplice quando si utilizza immutabile strutture, e di evitare le insidie di simile a questo:

// a struct
struct Interval {
   int From { get; set; }
   int To { get; set; }
}

// create a list of structs
List<Interval> intervals = new List<Interval>();

// add a struct to the list
intervals.Add(new Interval());

// try to set the values of the struct
intervals[0].From = 10;
intervals[0].To = 20;

Il risultato è che la struttura nell'elenco non è cambiato affatto.L'espressione Intervallo[0] copia il valore della struttura dall'elenco, quindi si modifica la proprietà del valore temporaneo, ma il valore non è mai messo nella lista.

Edit:Cambiato l'esempio utilizzare una lista invece di un array.

Quando copi le strutture intorno a te ne copi il contenuto, quindi se modifichi una versione copiata il " original " non verrà aggiornato.

Questa è una fonte di errori, poiché anche se sai di cadere nella trappola di copiare una struttura (semplicemente passandola a un metodo) e modificando la copia.

Mi è appena successo di nuovo la settimana scorsa, mi ha tenuto un'ora a cercare un bug.

Mantenere immutabili le strutture impedisce che ...

A parte questo, devi assicurarti di avere davvero una buona ragione per usare le strutture in primo luogo - " ottimizzazione " o " Voglio qualcosa che si alloca rapidamente nello stack " non conta come una risposta. Marshalling o cose da cui dipendi dal layout - ok, ma in genere non dovresti tenere quelle strutture in giro per molto tempo, sono valori non oggetti.

il motivo è necessario effettuare le strutture immutabile è che sono ValueTypes, il che significa che essi vengono copiati ogni volta che si passare a un metodo.

Così se, per esempio, era una proprietà che ha restituito una struttura, modificando il valore di un campo che la struttura sarebbe inutile, perché il getter sarebbe un ritorno copia della struttura, piuttosto che un riferimento per la struttura.Ho visto questo fatto nel codice, ed è spesso difficile da catturare.

Se la progettazione di strutture per l'immutabilità, il programmatore di evitare questi errori.

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