2010-01-13 31 views
26

Come dichiarare una costante locale in C#?Come dichiarare una costante locale in C#?

Come in Java, è possibile effettuare le seguenti operazioni:

public void f(){ 
    final int n = getNum(); // n declared constant 
} 

Come fare lo stesso in C#? Ho provato con readonly e const ma nessuno sembra funzionare.

Qualsiasi aiuto sarebbe molto apprezzato.

Grazie.

+11

Questa è l'omissione più fastidiosa da C# nella mia breve tempo di usarlo. Io uso const su variabili locali in C++ tutto il tempo per la mia sicurezza, sanità mentale e leggibilità. – pauldoo

+0

http://stackoverflow.com/questions/443687/why-does-c-sharp-disallow-readonly-local-variables –

+0

@MauricioScheffer, grazie per il link. Anche se ora devo scrivere qualcosa per .NET, userò sicuramente F #. :-) – missingfaktor

risposta

19

In C#, non è possibile creare una costante recuperata da un metodo.

Edit: link morto http://msdn.microsoft.com/en-us/library/e6w8fe1b(VS.71).aspx

Questo documento dovrebbe aiutare: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/const

Un'espressione costante è un'espressione che può essere pienamente valutata al momento della compilazione .

+14

Beh, questo fa schifo. :/ –

+5

Brutale. Non dovrei essere supportato, dovrebbe essere l'impostazione predefinita. – andyczerwonka

+0

'final' e' const' hanno significati diversi. In C#, un valore 'const' deve essere noto al momento della compilazione. Il vero problema è che C# non supporta le variabili locali 'readonly', il che è troppo brutto perché sarebbe utile. – Nick

6

Non sono sicuro del motivo per cui readonly e const non hanno funzionato per te poiché queste sono le parole chiave che ti servono. È utilizzare const se si dispone di un valore letterale (ad eccezione di letterali di array) e readonly altrimenti:

public void f() 
{ 
    const int answer = 42; 
} 

private readonly int[] array = new int[] { 1, 2, 3, 4 }; 
private readonly DateTime date = DateTime.Now; 
public void g() 
{ 
    Console.WriteLine(date.ToString()); 
} 

readonly funziona solo a livello di classe (che è, si può applicare solo ai campi). Anche come conseguenza di const che richiede un valore letterale, è intrinsecamente statico mentre un campo readonly può essere statico o di istanza.

+2

È importante notare che la creazione di un'istanza di sola lettura di un tipo di riferimento significa solo che il riferimento stesso non può essere modificato; l'oggetto può ancora essere modificato normalmente (a meno che il tipo non sia immutabile, come String). –

+3

La risposta alla ** tua ** domanda è semplice - nessuno di essi (const, readonly) funzionerebbe in un dato esempio. – greenoldman

1

La parola chiave const viene utilizzato per modificare una dichiarazione di un campo o variabile locale .

Da MSDN.

Poiché C# non può applicare "const correctnes" (come C++) in ogni caso, non penso che sia molto utile. Poiché le funzioni sono molto narrwoly scoped, è facile non perdere la supervisione.

+0

Devo sottolineare, tuttavia, che eric dahlvang ha ancora ragione sul perché const non ha funzionato nel tuo caso. –

+0

"Poiché le funzioni sono molto narrwoly scoped, è facile non perdere la supervisione." - Perché allora altri linguaggi come C++ e Java forniscono un meccanismo simile? – missingfaktor

+0

Non so di java, ma C++ può imporre true const anche sui riferimenti, cosa C# non può. Non ho mai visto const usato localmente da nessun'altra parte che in C++. –

1

Nell'esempio fornito, è necessario dichiarare la variabile come static, perché si sta inizializzando con una chiamata di metodo. Se si inizializza con un valore costante, ad esempio 42, è possibile utilizzare const. Per le classi, le strutture e gli array, readonly dovrebbe funzionare.

+7

Si noti che non è possibile utilizzare statico su variabili, solo sui membri. –

9

Dichiarare la variabile locale come variabile di iterazione. Le variabili di iterazione sono in sola lettura (non hai chiesto una soluzione carina).

public void f() 
{ 
    foreach (int n in new int[] { getNum() }) // n declared constant 
    { 
    n = 3; // won't compile: "error CS1656: Cannot assign to 'n' because it is a 'foreach iteration variable'" 
    } 
} 
+3

Buono a sapersi, ma dio promessa, non lo farò mai. – missingfaktor

+0

Questo è d'oro) Questo trucco è così brutto che non ci ho nemmeno pensato. Lo userò senz'altro (come snippet) per controllare il mio codice, sai, cambiando temporaneamente 'var index = GetNum()' in 'foreach' per forzare il compilatore a controllare il mio codice. –

+0

omg. Continuo a sbattere la testa sul tavolo mentre sto serenamente considerando di usare questo trucco. Che cosa veramente sporca ;-) –

2

Esiste un tipo di soluzione che richiede ReSharper. Non è possibile ottenere persone del luogo di sola lettura, ma è possibile almeno rilevare quelle mutate e colorarle in modo diverso.

Utilizzare la voce relativa ai caratteri e ai colori Identificatore di variabile locale variabile del ricondizionatore.

Per quanto mi riguarda, io ho i locali di colore grigio, e poi ho scelto un bianco in grassetto per le variabili mutati (questo è con un tema scuro). Ciò significa che qualsiasi variabile scritta più di una volta si presenta brillante rispetto a quella normale. Puoi quindi fare ciò che puoi per cercare di evitare di avere una variabile mutata, o se il metodo ne richiede davvero uno allora sarà almeno evidenziato.

+0

Non funziona per me. Mostra solo i contatori di loop come immutabili, tutto il resto è mutabile, non importa quante scritture. Immagino che il mio Resharper sia troppo vecchio :-) –

+0

@ Xan-KunClark-Davis non mostra ciò che è mutabile, mostra ciò che è mutato. tutto ciò che viene scritto esattamente una volta sembrerà normale. tutto ciò che è stato scritto due volte o più sarà evidenziato. (oh immagino tu abbia detto "non importa quante scritture"). sei sicuro? qualcosa come 'int x = 5; x = 3; ', x dovrebbe cambiare colore. Immagino che potrebbe essere la versione, sì. –

+0

@ Sahuagin Sì, ottengo la parte che devi invertire, tutti i locali ricevono l'evidenziatore e tutti i mutabili vengono "normalizzati" di nuovo, ma comunque non cambia il colore. Proverò di nuovo con un progetto pulito. –

Problemi correlati