stringa immutabile nell'array, tipo di riferimento e tipo di valore

1

Cercando di capire meglio le stringhe in C #

Queste asserzioni sono corrette?

  • string è immutabile
  • string è un tipo di riferimento ma si comporta come il tipo di valore

Per questi esempi di codice ...

string x = "one"   

(crea un'istanza di stringa che tiene "uno" in memoria)

x = "two"   

(distrugge l'istanza "one" e crea una nuova istanza di stringa che tiene "due" in memoria, anche se sta usando la stessa variabile x)

Se quanto sopra è corretto, cosa succede in una matrice di stringhe quando cambia un valore di indice?

string[] array = new string[2];

array[0] = "boo";   (string "boo" created and held in 0 index)
array[1] = "shoo";

array[0] = "moo";  

L'ultimo compito crea un intero nuovo array per cambiare boo in moo? La mia migliore "ipotesi" è che l'array contiene puntatori in modo che l'array [0] punti semplicemente alla nuova istanza di stringa che contiene "moo". È corretto? In caso contrario, qualcuno potrebbe, per favore, chiarire, grazie.

    
posta nanonerd 22.08.2016 - 17:40
fonte

4 risposte

1

Devi stare attento con alcune delle ipotesi che stai facendo riguardo alle stringhe. Il CLR ha una " una tabella, chiamata pool interno, che contiene una singola istanza di ogni costante di stringa letterale univoca dichiarata in un programma ". Quindi ciò che sta realmente accadendo nei tuoi esempi è:

string x = "one" // x references the "one" constant in the intern pool
x = "two" // x now references the "two" constant in the intern pool

array[0] = "boo"; // array[0] references the "boo" constant in the intern pool
array[1] = "shoo"; // array[1] references the "shoo" constant in the intern pool
array[0] = "moo"; // array[0] now references the "moo" constant in the intern pool
    
risposta data 22.08.2016 - 18:02
fonte
5

Una stringa è immutabile, corretta. Si comporta in qualche modo come un tipo di valore (incorporato), ma questa è principalmente una conseguenza dell'essere entrambi immutabili.

Un array non è immutabile, anche se gli elementi che contiene sono immutabili. Quindi se uno slot di matrice contiene una stringa, puoi cambiarla in una stringa diversa. Questo non cambia nessuna delle stringhe, cambia solo la matrice. Quindi sì, la tua ipotesi è corretta.

Una stringa è fondamentalmente un tipo di riferimento, il che significa che la variabile x in realtà non contiene una stringa, contiene un riferimento alla stringa. Quando si imposta la variabile su una stringa diversa, solo le modifiche che fanno riferimento alla variabile vengono mantenute, ma entrambe le stringhe non sono interessate. Stessa cosa con una serie di stringhe - non è in realtà una serie di stringhe ma piuttosto una serie di riferimenti alle stringhe. Quando modifichi un elemento dell'array, cambi solo la cella per contenere un riferimento diverso, ma nessuna delle stringhe effettive è interessata.

Quindi non è corretto dire che la stringa viene distrutta quando a una variabile viene assegnato un riferimento diverso. La stringa non è influenzata. (A causa della garbage collection, gli oggetti per i quali non esiste più riferimenti possono essere rimossi dalla memoria, ma questo è imprevedibile e specifico per l'implementazione.)

A proposito, nessuno di questi è influenzato dal fatto che le stringhe sono immutabili! Quello che descrivi è fondamentale per il funzionamento dei tipi di riferimento, e dal momento che stai modificando solo i riferimenti e non la stringa / oggetto stesso, non importa se è immutabile o meno.

    
risposta data 22.08.2016 - 18:00
fonte
5
string x = "one"   

(creates string instance holding "one" in memory)

Certo. E assegna un riferimento a quell'istanza alla variabile x.

x = "two"   

destroys "one" instance

No. Niente è distrutto qui. Non pensare alle stringhe come a cose che possono essere distrutte. E ricorda che lo scopo della raccolta dei rifiuti è quello di liberarti dall'aver dovuto ragionare sulla semantica della distruzione nel 99,9% dei casi.

creates new string instance holding "two" in memory, even though it is using the same variable x

Meglio sarebbe dire "e assegna un riferimento a quell'istanza alla variabile x".

What happens in a string array when one index value changes?

La stessa cosa.

string[] array = new string[2];
array[0] = "boo";   

string "boo" created and held in 0 index)

Sì.

array[1] = "shoo";
array[0] = "moo";  

Does the last assignment create an entire new array to change boo to moo?

No.

My best "guess" is that the array holds pointers so that array[0] simply points to the new string instance that holds "moo". Is this correct?

Sì!

Ma pensa a loro come riferimenti e non a puntatori . C # ha dei puntatori, che sono usati raramente e piuttosto diversi. Come dettaglio di implementazione, i riferimenti sono ovviamente dei puntatori dietro le quinte, ma non li consideri come indicatori. Pensa a loro come qualcosa che ha semantica di riferimento , perché è quello che ti garantiamo.

    
risposta data 22.08.2016 - 22:33
fonte
2

string x = "one" (creates string instance holding "one" in memory)

Forse. Se c'è un altro "uno" altrove, il runtime può riutilizzare l'istanza esistente.

x = "two" (destroys "one" instance and creates new string instance holding "two" in memory, even though it is using the same variable x)

Forse. Vedi sopra sul riutilizzo dell'istanza. Inoltre, nulla verrà distrutto immediatamente: il garbage collector gestisce ancora le stringhe.

If the above are correct, what happens in a string array when one index value changes?

Come sopra: rimuove un riferimento all'istanza della stringa che potrebbe renderlo disponibile per la garbage collection.

    
risposta data 22.08.2016 - 17:46
fonte

Leggi altre domande sui tag