Domanda

Avere un dibattito amichevole con un collega su questo. Abbiamo qualche idea a riguardo, ma ci chiediamo cosa ne pensi la folla SO?

È stato utile?

Soluzione

Uno dei motivi è che non esiste un supporto CLR per un locale di sola lettura. Readonly viene tradotto nel codice operativo iniziale CLR / CLI. Questo flag può essere applicato solo ai campi e non ha alcun significato per un locale. In effetti, applicarlo a un locale probabilmente produrrà un codice non verificabile.

Questo non significa che C # non possa farlo. Ma darebbe due significati diversi allo stesso costrutto linguistico. La versione per i locali non avrebbe alcuna mappatura equivalente CLR.

Altri suggerimenti

Penso che sia un cattivo giudizio da parte degli architetti C #. il modificatore di sola lettura sulle variabili locali aiuta a mantenere la correttezza del programma (proprio come le asserzioni) e può potenzialmente aiutare il compilatore a ottimizzare il codice (almeno nel caso di altre lingue). Il fatto che in questo momento non sia consentito in C # è un altro argomento secondo cui alcune delle caratteristiche di "quot" di C # sono semplicemente un'applicazione dello stile di codifica personale dei suoi creatori.

Rivolgendosi alla risposta di Jared, probabilmente dovrebbe essere solo una funzione di compilazione - il compilatore ti proibirebbe di scrivere sulla variabile dopo la dichiarazione iniziale (che dovrebbe includere un compito).

Posso vedere valore in questo? Potenzialmente - ma non molto, a dire il vero. Se non riesci a stabilire facilmente se una variabile verrà assegnata o meno in un'altra parte del metodo, il tuo metodo è troppo lungo.

Per quello che vale, Java ha questa funzione (usando il modificatore final ) e molto raramente l'ho vista usata se non nei casi in cui deve essere usato per consentire alla variabile di essere catturata da una classe interna anonima - e dove viene usata , mi dà un'impressione di disordine piuttosto che informazioni utili.

Una proposta locali e parametri di sola lettura for è stato brevemente discusso dal team di progettazione di C # 7. Da Note sulla riunione di Design C # del 21 gennaio 2015 :

  

I parametri e i locali possono essere catturati da lambdas e quindi accessibili contemporaneamente, ma non c'è modo di proteggerli da problemi di stato reciproco: non possono essere di sola lettura.

     

In generale, la maggior parte dei parametri e molti locali non devono mai essere assegnati dopo aver ottenuto il loro valore iniziale. Autorizzarli di sola lettura esprimerebbe chiaramente questo intento.

     

Un problema è che questa funzione potrebbe essere un "fastidio attraente". Considerando che la "cosa giusta" fare sarebbe quasi sempre fare parametri e gente del posto in sola lettura, ingombrare il codice in modo significativo per farlo.

     

Un'idea per alleviare parzialmente questo è quella di consentire alla combinazione di sola lettura var su una variabile locale di essere contratta a val o qualcosa di simile. Più in generale, potremmo provare a pensare semplicemente a una parola chiave più corta di quella stabilita di sola lettura per esprimere la leggerezza.

La discussione continua nel repository C # Language Design. Vota per mostrare il tuo supporto. https://github.com/dotnet/csharplang/issues/188

Ero quel collega e non era amichevole! (sto scherzando)

Non eliminerei la funzione perché è meglio scrivere metodi brevi. È un po 'come dire che non dovresti usare i thread perché sono difficili. Dammi il coltello e lasciami essere responsabile di non tagliarmi.

Personalmente, volevo un altro " var " digitare la parola chiave come " inv " (invarente) o "rvar" per evitare il disordine. Ho studiato F # negli ultimi tempi e trovo la cosa immutabile allettante.

Non ho mai saputo che Java avesse questo.

Vorrei le variabili locali di sola lettura nello stesso modo in cui mi piacciono le variabili locali const . Ma ha meno priorità rispetto ad altri argomenti.
Forse la sua priorità è la stessa ragione per cui i progettisti di C # non hanno (ancora!) implementare questa funzione. Ma dovrebbe essere facile (e compatibile con le versioni precedenti) supportare variabili locali di sola lettura nelle versioni future.

È una svista per il progettista del linguaggio c #. F # ha una parola chiave val ed è basato su CLR. Non c'è motivo per cui C # non possa avere la stessa funzione di lingua.

Sola lettura significa che l'unico posto in cui è possibile impostare la variabile di istanza è nel costruttore. Quando si dichiara una variabile localmente non ha un'istanza (è solo nell'ambito) e non può essere toccata dal costruttore.

Lo so, questo non risponde al perché della tua domanda. Ad ogni modo, coloro che leggono questa domanda potrebbero comunque apprezzare il codice qui sotto.

Se sei davvero preoccupato di sparare a te stesso nel piede quando esegui l'override di una variabile locale che dovrebbe essere impostata una sola volta e non vuoi renderla una variabile più accessibile a livello globale, potresti fare qualcosa del genere.

    public class ReadOnly<T>
    {
        public T Value { get; private set; }

        public ReadOnly(T pValue)
        {
            Value = pValue;
        }

        public static bool operator ==(ReadOnly<T> pReadOnlyT, T pT)
        {
            if (object.ReferenceEquals(pReadOnlyT, null))
            {
                return object.ReferenceEquals(pT, null);
            }
            return (pReadOnlyT.Value.Equals(pT));
        }

        public static bool operator !=(ReadOnly<T> pReadOnlyT, T pT)
        {
            return !(pReadOnlyT == pT);
        }
    }

Esempio di utilizzo:

        var rInt = new ReadOnly<int>(5);
        if (rInt == 5)
        {
            //Int is 5 indeed
        }
        var copyValueOfInt = rInt.Value;
        //rInt.Value = 6; //Doesn't compile, setter is private

Forse non meno codice di rvar rInt = 5 ma funziona.

Puoi dichiarare le variabili locali di sola lettura in C #, se stai usando il compilatore interattivo C # csi :

>"C:\Program Files (x86)\MSBuild\14.0\Bin\csi.exe"
Microsoft (R) Visual C# Interactive Compiler version 1.3.1.60616
Copyright (C) Microsoft Corporation. All rights reserved.

Type "#help" for more information.
> readonly var message = "hello";
> message = "goodbye";
(1,1): error CS0191: A readonly field cannot be assigned to (except in a constructor or a variable initializer)

Puoi anche dichiarare solo variabili locali nel formato di script .csx .

c # ha già una var di sola lettura, sebbene in una sintassi leggermente diversa:

Considera le seguenti righe:

var mutable = myImmutableCalculationMethod();
readonly var immutable = mutable; // not allowed in C# 8 and prior versions
return immutable;

Confronta con:

var mutable = myImmutableCalculationMethod();
string immutable() => mutable; // allowed in C# 7
return immutable();

Certamente, la prima soluzione potrebbe essere meno codice da scrivere. Ma il secondo frammento renderà esplicito il readonly, quando si fa riferimento alla variabile.

Penso che sia perché una funzione che ha una variabile di sola lettura non può mai essere chiamata, e probabilmente c'è qualcosa al di fuori del suo ambito di applicazione, e quando dovresti farlo?

usa la parola chiave const per rendere variabile di sola lettura.

riferimento: https://docs.microsoft .com / it-it / dotnet / csharp / lingua-reference / parole chiave / const

public class SealedTest
{
    static void Main()
    {
        const int c = 707;
        Console.WriteLine("My local constant = {0}", c);
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top