In .Net perché String.Empty viene letto solo anziché una costante? Mi chiedo solo se qualcuno sa qual era il ragionamento alla base di quella decisione.
In .Net perché String.Empty viene letto solo anziché una costante? Mi chiedo solo se qualcuno sa qual era il ragionamento alla base di quella decisione.
Risposte:
Il motivo che static readonly
viene utilizzato invece di const
è dovuto all'uso con codice non gestito, come indicato da Microsoft qui nella versione Common Source Infrastructure 2.0 di Shared Source . Il file da guardare è sscli20\clr\src\bcl\system\string.cs
.
La costante vuota contiene il valore di stringa vuota. Dobbiamo chiamare il costruttore String in modo che il compilatore non lo contrassegni come letterale.
Contrassegnare questo come letterale significherebbe che non si presenta come un campo a cui possiamo accedere da nativi.
Ho trovato queste informazioni da questo utile articolo su CodeProject .
String.Empty
più solo per quel motivo.
Penso che ci sia molta confusione e cattive risposte qui.
Innanzitutto, i const
campi sono static
membri ( non membri dell'istanza ).
Controlla la sezione 10.4 Costanti delle specifiche del linguaggio C #.
Anche se le costanti sono considerate membri statici, una dichiarazione costante non richiede né consente un modificatore statico.
Se i public const
membri sono statici, non si potrebbe considerare che una costante creerà un nuovo oggetto.
Detto questo, le seguenti righe di codice fanno esattamente la stessa cosa rispetto alla creazione di un nuovo Oggetto.
public static readonly string Empty = "";
public const string Empty = "";
Ecco una nota di Microsoft che spiega la differenza tra i 2:
La parola chiave readonly è diversa dalla parola chiave const. Un campo const può essere inizializzato solo alla dichiarazione del campo. Un campo di sola lettura può essere inizializzato nella dichiarazione o in un costruttore. Pertanto, i campi di sola lettura possono avere valori diversi a seconda del costruttore utilizzato. Inoltre, mentre un campo const è una costante di compilazione, il campo di sola lettura può essere utilizzato per le costanti di runtime, ...
Quindi trovo che l'unica risposta plausibile qui sia quella di Jeff Yates.
const string
e static readonly string
faccio la stessa cosa. I valori costanti vengono sostituiti nel codice collegato mentre vengono referenziati i valori di sola lettura statici. Se si dispone di una const
libreria A utilizzata dalla libreria B, la libreria B sostituirà tutti i riferimenti a quella const
variabile con il suo valore letterale; se static readonly
invece fosse quella variabile , verrebbe referenziato e il suo valore determinato in fase di esecuzione.
String.Empty read only instead of a constant?
Se si rende costante una stringa , il compilatore viene sostituito con la stringa effettiva ovunque la si chiami e si riempie il codice con la stessa stringa dappertutto e quando il codice viene eseguito è necessario leggere ancora e ancora quella stringa dalla memoria diversa dati.
Se lasci la tua stringa letta solo in una posizione così com'è String.Empty
, il programma mantiene la stessa stringa solo in una posizione e la legge, o fai riferimento ad essa - mantenendo i dati nella memoria minima.
Inoltre, se si compila una dll usando String.Empty come const e, per qualsiasi motivo, la modifica String.Empty, la dll compilata non funzionerà più allo stesso modo, poiché cost
crea il codice interno per conservare effettivamente una copia della stringa ad ogni chiamata.
Vedi questo codice per esempio:
public class OneName
{
const string cConst = "constant string";
static string cStatic = "static string";
readonly string cReadOnly = "read only string";
protected void Fun()
{
string cAddThemAll ;
cAddThemAll = cConst;
cAddThemAll = cStatic ;
cAddThemAll = cReadOnly;
}
}
verrà dal compilatore come:
public class OneName
{
// note that the const exist also here !
private const string cConst = "constant string";
private readonly string cReadOnly;
private static string cStatic;
static OneName()
{
cStatic = "static string";
}
public OneName()
{
this.cReadOnly = "read only string";
}
protected void Fun()
{
string cAddThemAll ;
// look here, will replace the const string everywhere is finds it.
cAddThemAll = "constant string";
cAddThemAll = cStatic;
// but the read only will only get it from "one place".
cAddThemAll = this.cReadOnly;
}
}
e la chiamata dell'assemblea
cAddThemAll = cConst;
0000003e mov eax,dword ptr ds:[09379C0Ch]
00000044 mov dword ptr [ebp-44h],eax
cAddThemAll = cStatic ;
00000047 mov eax,dword ptr ds:[094E8C44h]
0000004c mov dword ptr [ebp-44h],eax
cAddThemAll = cReadOnly;
0000004f mov eax,dword ptr [ebp-3Ch]
00000052 mov eax,dword ptr [eax+0000017Ch]
00000058 mov dword ptr [ebp-44h],eax
Modifica: errore di battitura corretto
Questa risposta esiste per scopi storici.
Originariamente:
Perché String
è una classe e quindi non può essere una costante.
Discussione estesa:
Molte utili finestre di dialogo sono state messe a punto nel vagliare questa risposta e, anziché eliminarla, questo contenuto viene riprodotto direttamente:
In .NET, (diversamente da Java), stringa e stringa sono esattamente le stesse. E sì, puoi avere costanti letterali di stringa in .NET - DrJokepu, 3 febbraio 2009 alle 16:57
Stai dicendo che una classe non può avere costanti? - StingyJack, 3 febbraio 2009 alle 16:58
Sì, gli oggetti devono essere usati in sola lettura. Solo le strutture possono fare costanti. Penso che quando usi al
string
posto delString
compilatore cambi la const in sola lettura per te. Tutto a che fare con la felicità dei programmatori C. - Garry Shutler, 3 febbraio 2009 alle 16:59tvanfosson lo ha appena spiegato in modo un po 'più dettagliato. "X non può essere una costante, perché contenere Y è una classe" era un po 'troppo privo di contesto;) - Leonidas 3 febbraio 2009 alle 17:01
string.Empty è una proprietà statica che restituisce un'istanza della classe String, ovvero la stringa vuota, non la classe di stringa stessa. - Tvanfosson, 3 febbraio 2009 alle 17:01
Vuoto è un'istanza di sola lettura (non è una proprietà) della classe String. - senfo, 3 febbraio 2009 alle 17:02
Mi fa male la testa. Penso ancora di avere ragione, ma ora ne sono meno certo. Stasera sono necessarie ricerche! - Garry Shutler, 3 febbraio 2009 alle 17:07
La stringa vuota è un'istanza della classe di stringa. Vuoto è un campo statico (non una proprietà, sto corretto) sulla classe String. Fondamentalmente la differenza tra un puntatore e la cosa a cui punta. Se non fosse di sola lettura, potremmo cambiare a quale istanza si riferisce il campo vuoto. - tvanfosson, 3 febbraio 2009 alle 17:07
Garry, non devi fare nessuna ricerca. Pensaci. String è una classe. Vuoto è un'istanza di una stringa. - senfo, 3 febbraio 2009 alle 17:12
C'è qualcosa che non capisco: come mai il costruttore statico della classe String può creare un'istanza della classe String? Non è forse una specie di scenario "pollo o l'uovo"? - DrJokepu, 3 febbraio 2009 alle 17:12 5
Questa risposta sarebbe corretta per quasi tutte le altre classi tranne System.String. .NET offre molte prestazioni speciali per le stringhe e una di queste è che PUOI avere costanti di stringa, provaci. In questo caso, Jeff Yates ha la risposta corretta. - Joel Mueller, 3 febbraio 2009 alle 19:25
Come descritto nel §7.18, un'espressione costante è un'espressione che può essere completamente valutata in fase di compilazione. Poiché l'unico modo per creare un valore non nullo di un tipo di riferimento diverso da stringa è applicare il nuovo operatore e poiché il nuovo operatore non è consentito in un'espressione costante, l'unico valore possibile per le costanti dei tipi di riferimento diverso da stringa è nullo. I due precedenti commenti sono stati presi direttamente dalle specifiche del linguaggio C # e ribadiscono ciò di cui ha parlato Joel Mueller. - senfo, 4 febbraio 2009 alle 15:05 5