Gli array o gli elenchi vengono passati per impostazione predefinita per riferimento in c #?


86

Fanno? O per velocizzare il mio programma dovrei passarli per riferimento?


35
Per velocizzare il tuo programma dovresti (1) fissare obiettivi significativi, (2) testare per vedere se hai raggiunto i tuoi obiettivi, (3) se non l'hai fatto, utilizzare uno strumento di profilazione per trovare la cosa più lenta e (4 ) ottimizza la cosa più lenta.
Eric Lippert,


3
@EricLippert Il tuo commento risponde alla vera domanda dell'OP molto meglio di qualsiasi altra risposta pubblicata. Tutti erano così distratti dagli aspetti tecnici del "passaggio di riferimento in base al valore" che hanno completamente trascurato la vera domanda sull'ottimizzazione delle prestazioni. Sfortunatamente l'OP ha comunicato le sue esigenze piuttosto male, e le altre risposte almeno aiuteranno il pubblico di Google.
Dan Bechard

"altre risposte aiuteranno almeno il pubblico di Google" - lo faranno! :)
miki

Risposte:


210

Il riferimento viene passato per valore .

Gli array in .NET sono oggetti nell'heap, quindi hai un riferimento. Quel riferimento viene passato per valore, il che significa che le modifiche al contenuto dell'array saranno viste dal chiamante, ma la riassegnazione dell'array non:

void Foo(int[] data) {
    data[0] = 1; // caller sees this
}
void Bar(int[] data) {
    data = new int[20]; // but not this
}

Se aggiungi il refmodificatore, il riferimento viene passato per riferimento e il chiamante vedrebbe una delle modifiche sopra.


28
La risposta è corretta ma odio da compagnia le persone che affermano "il riferimento è passato per valore". Confonde il problema. Sì, i riferimenti (indirizzi di memoria) vengono passati per valore, ma non era questo il problema.
WernerVA

9
@WernerVA Mi interessa come pensi che lo esprimeresti in modo diverso che rimane corretto e inequivocabile
Marc Gravell

2
Non lo esprimerei diversamente, forse solo con un po 'più di dettaglio.
WernerVA

Questo non risponde alla parte relativa alla velocità della domanda. Probabilmente è ovvio per te che l'ottimizzazione di una copia di riferimento sarà completamente trascurabile rispetto alle centinaia di altre operazioni molto più costose in corso, ma l'OP lo ha chiesto specificamente.
Dan Bechard

7
@Dan la parte relativa alla velocità è intrinsecamente collegata al "se l'array viene passato per valore, ovvero una copia del contenuto dell'array, significa un'allocazione e una copia di tutta la memoria". Poiché si tratta di un riferimento che viene passato, non ci sono domande sulla performance a cui rispondere: quella parte della domanda viene resa discutibile e risponde automaticamente. Tranne che ora è anche risposto qui esplicitamente nei commenti ...
Marc Gravell

10

Vengono passati per valore (come lo sono tutti i parametri che non sono né ref né out), ma il valore è un riferimento all'oggetto, quindi vengono effettivamente passati per riferimento.


0

Sì, vengono passati per riferimento per impostazione predefinita in C #. Tutti gli oggetti in C # lo sono, ad eccezione dei tipi di valore. Per essere un po 'più precisi, vengono passati "per riferimento per valore"; ovvero, il valore della variabile che vedi nei tuoi metodi è un riferimento all'oggetto originale passato. Questo è un piccolo punto semantico, ma a volte può essere importante.


9
Il riferimento viene passato per valore; che è molto diverso da "sono passati per riferimento".
Marc Gravell

1
Questo è l'esatto opposto della verità. Citando questo post di John Skeet : "Per impostazione predefinita, tutti i parametri vengono passati per valore in C #. I parametri vengono passati solo per riferimento se includi esplicitamente un modificatore out o ref. Tuttavia, devi essere consapevole del fatto che quando il tipo del parametro è un tipo di riferimento, stai passando un riferimento piuttosto che un oggetto reale ". È solo il riferimento (l'indirizzo di memoria) che viene passato per valore.
alexlomba87
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.