Ho varie costanti che il mio programma usa ... string
's, int
' s, double
's, ecc ... Qual è il modo migliore per memorizzarle? Non penso di volere uno Enum
, perché i dati non sono tutti dello stesso tipo e desidero impostare manualmente ciascun valore. Devo solo archiviarli tutti in una classe vuota? O c'è un modo migliore?Qual è il modo migliore per memorizzare un gruppo di costanti che utilizza il mio programma?
risposta
Probabilmente si potrebbero avere in una classe statica, con proprietà statiche di sola lettura.
public static class Constants
{
public static string SomeConstant { get { return "Some value"; } }
}
grrr .. 40 secondi più veloce sul sorteggio :) –
+1, ma ancora meglio se è possibile estrarli da un file di risorse per la localizzazione. –
Sembra un po 'prolisso - perché non stringhe statiche readonly? – emptyset
L'IMO che utilizza una classe piena di costanti va bene per le costanti. Se cambieranno semi-occasionalmente, ti consiglio di utilizzare AppSettings nella tua configurazione e invece nella classe ConfigurationManager.
Quando ho "costanti" che sono effettivamente richiamate da AppSettings o simili, avrò sempre una classe "costanti" che avvolge la lettura dal Configuration Manager. È sempre più significativo avere Constants.SomeModule.Setting
invece di dover ricorrere direttamente a ConfigurationManager.AppSettings["SomeModule/Setting"]
in qualsiasi luogo che voglia consumare il suddetto valore di impostazione.
I punti bonus per questa configurazione, poiché SomeModule
potrebbero essere una classe nidificata all'interno del file Constants, è possibile utilizzare facilmente Dependency Injection per iniettare SomeModule
direttamente nelle classi che dipendono da esso. È anche possibile estrarre un'interfaccia in cima a SomeModule
e quindi creare una dipendenza a ISomeModuleConfiguration
nel proprio codice utente, in tal modo si consentirebbe di separare la dipendenza dai file di Costanza e persino di rendere più semplice il test, specialmente se queste impostazioni provengono da AppSettings e li cambi utilizzando le trasformazioni di configurazione perché le impostazioni sono specifiche per l'ambiente.
Solo per aggiungere a questo: il motivo è che quando si costruisce, le costanti usate da altri assiemi non vengono aggiornate. Ciò significa che se hai AssemblyA e AssemblyB e B usa una costante da A, il valore viene copiato, non referenziato, quindi ricostruire A non aggiornerà B. Ciò può portare a strani bug. –
@CamiloMartin ci sono molti modi per gestirlo, le tue "costanti" potrebbero solo leggere statiche per evitarlo, o come ho detto se cambiano più di una volta in una luna blu per usare il ConfigurationManager. –
Sì, stavo solo dicendo che non è solo perché è una convenzione che si dovrebbe usare in lettura statica, ma perché in realtà può essere fonte di confusione. Inoltre, un'alternativa a ConfigurationManager sono i file di risorse: devi solo aggiungere un altro file di risorse con un codice di lingua nel nome e il tuo codice verrà localizzato istantaneamente. –
Quello che mi piace fare è il seguente (ma assicuratevi di leggere fino alla fine di utilizzare la corretta tipo di costanti):
internal static class ColumnKeys
{
internal const string Date = "Date";
internal const string Value = "Value";
...
}
Read this sapere perché const
potrebbe non essere ciò che vuoi. Possibile tipo di costanti sono:
const
campi. Non utilizzare tra gli assembly (public
oprotected
) se il valore potrebbe cambiare in futuro perché il valore sarà hardcoded in fase di compilazione in quegli altri assembly. Se si modifica il valore, il vecchio valore verrà utilizzato dagli altri assembly fino a quando non vengono ricompilati.static readonly
campistatic
struttura senzaset
Perché di sola lettura se utilizzato su più assiemi? –
Perché la lettura statica funziona meglio con più assiemi rispetto a const? –
I valori di Const vengono copiati dal gruppo di origine nel codice compilato. Ciò significa che se si deve modificare un valore const, tutti gli assembly dipendenti DEVONO essere ricompilati rispetto alla nuova versione. Più sicuro e più comodo da usare statico readonly. – cfeduke
Una classe statica vuoto è appropriato. Prendi in considerazione l'utilizzo di diverse classi, in modo da ottenere buoni gruppi di costanti correlate e non un gigantesco file Globals.cs.
Inoltre, per alcune costanti int, prendere in considerazione la notazione:
[Flags]
enum Foo
{
}
quanto questo permette di treating the values like flags.
"Considerare l'utilizzo di più classi, in modo da ottenere buoni gruppi di costanti correlate e non un gigantesco file Globals.cs." Credo che questa sia la migliore raccomandazione, non ci sono alcuni schemi di progettazione attorno a questo? Non ne conosco nessuno per nome, vero? –
Sì, un static class
per la memorizzazione di costanti andrebbe bene, ad eccezione delle costanti relative a tipi specifici.
questo è esattamente quello che sto cercando di fare. Voglio che si presentino come membri della classe per cui sono. ma non voglio aggiungerli alle classi perché le costanti variano a seconda della compagnia per cui lavoro. non ho ancora trovato nulla sulle costanti o proprietà di estensione. ma potrei abbandonare questa idea perché non voglio che vengano visualizzati come membri quando serializzo queste classi – symbiont
Un altro voto per l'utilizzo di web.config o app.config. I file di configurazione sono un buon posto per costanti come stringhe di connessione, ecc. Preferisco non dover guardare all'origine per visualizzare o modificare questo tipo di cose. Una classe statica che legge queste costanti da un file .config potrebbe essere un buon compromesso, in quanto consente alla tua applicazione di accedere a queste risorse come se fossero definite nel codice, ma ti offre comunque la flessibilità di averli in una vista facilmente visualizzabile/modificabile spazio.
Una stringa di connessione non è una costante, è un'impostazione. Potrebbe essere che l'OP * in realtà * significhi anche le impostazioni, piuttosto che le costanti, ma non vedo alcuna prova per questo. –
Mi permetto di dissentire. I valori letterali stringa sono costanti per definizione. Cambiare la stringa in un file di configurazione equivale all'incirca a cambiarlo nel codice e ricompilarlo; sarebbe * quello * non renderlo costante? Io non la penso così –
@David - Non vero. Un compilatore non si preoccupa di quale valore si ha nel proprio file di configurazione - questo viene letto in fase di runtime. –
Questo è il modo migliore IMO. Non c'è bisogno di proprietà, o di sola lettura:
public static class Constants
{
public const string SomeConstant = "Some value";
}
Se si intende utilizzare const, esporre solo come interno. Non rendere pubblico const (anche se pensi che i tuoi assembly non verranno utilizzati all'esterno della tua organizzazione). Inoltre, le proprietà offrono flessibilità programmatica per l'espansione futura senza la necessità di ridefinire l'interfaccia. – cfeduke
Se queste costanti sono riferimenti di servizio o interruttori tal senso il comportamento dell'applicazione li vorrei impostare come impostazioni utente dell'applicazione. In questo modo se hanno bisogno di essere modificati non è necessario ricompilare e si può ancora fare riferimento a loro attraverso la classe delle proprietà statiche.
Properties.Settings.Default.ServiceRef
Suggerirei una classe statica con readon statico. Si prega di trovare il frammento di codice qui sotto:
public static class CachedKeysManager
{
public static readonly string DistributorList = "distributorList";
}
In qualsiasi modo tu lo desideri, è così che ti serve. –