2010-06-25 7 views
8

Perché String è stato progettato come tipo di riferimento anziché come tipo di valore?C'è qualche altro motivo oltre alle prestazioni e alla leggibilità del motivo per cui System.String è un tipo di riferimento anziché di tipo valore?

Dal punto di vista della modellazione, l'avrei modellato come un tipo di valore poiché rappresenta qualcosa senza identità. Non ha attributi distintivi. (Ad esempio, non posso fare alcuna differenza tra una stringa "a" e un'altra stringa "a")

So che avrei avuto seri problemi di prestazioni con lunghe stringhe memorizzate nello stack. Probabilmente è impossibile, poiché le stringhe diventano molto lunghe, perché lo stack è di dimensioni limitate.

Se non fosse per le prestazioni perché si progetta System.String come un tipo di riferimento? (Si supponga qualsiasi stringa possibile è al massimo 16 byte di lunghezza)

+3

Immagino di aver già visto la risposta per il potenziale duplicato http://stackoverflow.com/questions/636932/in-c-why-is-string-a-reference-type-that-behaves-like-a -valore-tipo. Tuttavia, non sono sicuro del tipo di risposta che stai cercando: se stai parlando di .NET framework engineering, il motivo principale (dato nell'altro thread) è che le stringhe possono avere qualsiasi dimensione e potrebbero facilmente riempire l'1 MB stack - non solo porta a problemi di prestazioni, ma interrompe apertamente il framework. Hai bisogno di un motivo migliore del "non avere una struttura infranta"? –

+0

Sto cercando una risposta dal punto di vista della modellazione. (Ad esempio una risposta del tipo: la modellerei come un tipo di riferimento anche se non fosse per le prestazioni e lo stack perché ...) –

+3

Ma l'unica ragione per cui esistono anche i tipi di valore è a causa delle prestazioni. Se qualcuno modellasse un puro linguaggio OOP (come SmallTalk), allora * mai * renderebbe i tipi di comportamento differenti in modo così drammatico. E una stringa e un int sarebbero entrambi oggetti. E sii lento come melassa, come SmallTalk. –

risposta

2

Gli edifici devono essere impostati su. Pensa ad un string[], per esempio. L'unico modo in cui si potrebbe avere string come valore-tipo sarebbe quello di memorizzare solo il puntatore. Quale è essenzialmente ciò che otteniamo utilizzando un tipo di riferimento.

Naturalmente, è anche enormemente utile non copiare la stringa ogni volta che viene assegnata.

1

la mia comprensione è che le stringhe sono classi immutabili, invece di strutture solo come un guadagno di prestazioni.

Le stringhe tendono a essere create e quindi passate a molti oggetti per il rendering a un utente o la consegna ad altri sistemi. Dopo la loro creazione, le stringhe tendono a non cambiare, quindi copiare l'intero array di caratteri come un valore univoco in ciascun oggetto ha scarso valore pratico e crea molti oggetti temporanei.

1

Semplice - perché io non voglio fare copie di stringhe ogni volta che passo uno in un metodo. Ci vuole più memoria e ci vuole più tempo.

+0

Credo che l'OP abbia detto "oltre alle prestazioni". –

5

Come si fa notare, il fatto che un tipo di valore che può diventare molto elevato potrebbe essere proibitivo a causa dello spazio limitato nello stack e della semantica della copia in uso dei tipi di valore.

Inoltre, il modo in cui le stringhe vengono implementate in .NET aggiunge un paio di elementi all'equazione. Le stringhe non sono solo tipi di riferimento, sono anche immutabili (al di fuori del namespace System comunque) e il runtime usa interning per fare trucchi perfetti per le stringhe.

Tutto questo aggiunge un paio di vantaggi: le stringhe letterali duplicate vengono memorizzate solo una volta e il confronto di tali stringhe diventa estremamente efficace in quanto è possibile confrontare i riferimenti anziché i flussi di caratteri Unicode. Quelle opzioni non sarebbero possibili per i tipi di valore.

0

  • ~ modificato per rispondere alla domanda in modo più accurato

Un punto è che il tipo String come in molte lingue è codificato come Unicode e quindi è illogico trattarli come tipi primitivi (come int) in quanto non vi è alcuna corrispondenza diretta tra la sua codifica binaria e la sua forma di lettura umana.

Il livello Unicode qualifica automaticamente i tipi di stringa da sottrarre da binario, mentre i numeri sono intercambiabili tra base 2 (binario) e 10 di base (decimale) moduli con relativa facilità.

Il motivo per cui le variabili primitive possono risiedere nello stack è che c'è molto spazio disponibile per molti numeri. Questo non è il caso per il più dati pesantiString tipo.

I tipi di operazioni eseguite su stringhe non sono realmente aritmetici, ma più basati su logica booleana (eccetto quando si contano le stringhe quando vengono trattati come un vettore o un array), quindi ha senso ottimizzare la struttura dati per i suoi usi primari , tramite lo spazio dei nomi System.String.

0

In termini di equlity, è ancora possibile considerarlo come valore di tipo con l'operatore == .

Quindi, se mai, è giusto e vantaggio avere come riferimento no?

Problemi correlati