Avoir un débat amical avec un collègue à ce sujet. Nous avons quelques réflexions à ce sujet, mais nous nous demandons ce que la foule SO en pense?
c#
immutability
language-design
readonly
Brian Genisio
la source
la source
Réponses:
L'une des raisons est qu'il n'y a pas de support CLR pour un local en lecture seule. Readonly est traduit dans l'opcode initonly CLR / CLI. Cet indicateur ne peut être appliqué qu'aux champs et n'a aucune signification pour un local. En fait, l'appliquer à un local produira probablement un code invérifiable.
Cela ne signifie pas que C # ne peut pas faire cela. Mais cela donnerait deux significations différentes à la même construction de langage. La version pour les locaux n'aurait pas de mappage équivalent CLR.
la source
readonly
mot-clé pour les champs doit être pris en charge par l'interface de ligne de commande car son effet est visible par les autres assemblys. Tout cela signifierait que la variable n'a qu'une seule affectation dans la méthode au moment de la compilation.const
(qui en C ++ ressemble plus à C #readonly
qu'à C #const
, bien qu'il puisse jouer les deux rôles). Pourtant, C ++ prend en chargeconst
la variable automatique locale. Par conséquent, le manque de support CLR pour un C #readonly
pour une variable locale n'est pas pertinent.using
etout
font exactement cela et le monde ne s'est pas effondré.Je pense que c'est un mauvais jugement de la part des architectes C #. Le modificateur readonly sur les variables locales aide à maintenir l'exactitude du programme (tout comme les assertions) et peut potentiellement aider le compilateur à optimiser le code (au moins dans le cas d'autres langages). Le fait qu'il soit interdit en C # pour le moment, est un autre argument selon lequel certaines des "fonctionnalités" de C # sont simplement une application du style de codage personnel de ses créateurs.
la source
Pour répondre à la réponse de Jared, il faudrait probablement juste une fonctionnalité de compilation - le compilateur vous interdirait d'écrire dans la variable après la déclaration initiale (qui devrait inclure une affectation).
Puis-je voir la valeur à cela? Potentiellement - mais pas beaucoup, pour être honnête. Si vous ne pouvez pas facilement dire si une variable va être affectée ailleurs dans la méthode, alors votre méthode est trop longue.
Pour ce que ça vaut, Java a cette fonctionnalité (en utilisant le
final
modificateur) et je l'ai très rarement vue utilisée sauf dans les cas où elle doit être utilisée pour permettre à la variable d'être capturée par une classe interne anonyme - et où elle se trouve utilisé, cela me donne une impression de fouillis plutôt que d'informations utiles.la source
readonly
/final
des variables avec ses motsval
-var
clés et . Dans le code Scala, les locauxval
sont très fréquemment utilisés (et sont, en fait, préférés aux locauxvar
). Je soupçonne que les principales raisons pour lesquelles lefinal
modificateur n'est pas utilisé plus fréquemment en Java sont a) l'encombrement et b) la paresse.readonly
ce ne serait pas trop important. D'un autre côté, pour les variables locales qui sont utilisées dans les fermetures,readonly
laisserait dans de nombreux cas le compilateur générer du code plus efficace. Actuellement, quand l'exécution entre dans un bloc qui contient une fermeture, le compilateur doit créer un nouvel objet de tas pour les variables fermées, même si aucun code qui utiliserait la fermeture n'est jamais exécuté . Si une variable était en lecture seule, le code en dehors de la fermeture pourrait utiliser une variable normale; seulement quand un délégué est créé pour la fermeture ...Une proposition en lecture seule pour les sections locales et les paramètres a été brièvement discutée par l'équipe de conception C # 7. À partir des notes de la réunion C # Design du 21 janvier 2015 :
La discussion se poursuit dans le référentiel C # Language Design. Votez pour montrer votre soutien. https://github.com/dotnet/csharplang/issues/188
la source
C'est un oubli pour le concepteur de langage c #. F # a le mot clé val et il est basé sur CLR. Il n'y a aucune raison pour laquelle C # ne peut pas avoir la même fonctionnalité de langage.
la source
J'étais ce collègue et ce n'était pas sympathique! (je rigole)
Je n'éliminerais pas la fonctionnalité car il vaut mieux écrire des méthodes courtes. C'est un peu comme dire que vous ne devriez pas utiliser de threads parce qu'ils sont durs. Donnez-moi le couteau et laissez-moi être responsable de ne pas me couper.
Personnellement, je voulais un autre mot-clé de type "var" comme "inv" (invarient) ou "rvar" pour éviter l'encombrement. J'ai récemment étudié F # et je trouve la chose immuable attrayante.
Je n'ai jamais su que Java avait ça.
la source
Je voudrais des variables locales en lecture seule de la même manière que j'aime les variables const locales . Mais il a moins de priorité que d'autres sujets.
Peut-être que sa priorité est la même raison pour les concepteurs C # de ne pas (encore!) Implémenter cette fonctionnalité. Mais il devrait être facile (et rétrocompatible) de prendre en charge les variables locales en lecture seule dans les versions futures.
la source
Readonly signifie que le seul endroit où la variable d'instance peut être définie est dans le constructeur. Lors de la déclaration d'une variable localement, elle n'a pas d'instance (elle est juste dans la portée), et elle ne peut pas être touchée par le constructeur.
la source
Je sais, cela ne répond pas au pourquoi de votre question. Quoi qu'il en soit, ceux qui liront cette question apprécieront peut-être le code ci-dessous.
Si vous êtes vraiment préoccupé par le fait de vous tirer une balle dans le pied lors de la substitution d'une variable locale qui ne devrait être définie qu'une seule fois, et que vous ne voulez pas en faire une variable plus accessible globalement, vous pouvez faire quelque chose comme ça.
Exemple d'utilisation:
Peut-être pas moins de code
rvar rInt = 5
mais ça marche.la source
Vous pouvez déclarer des variables locales en lecture seule en C #, si vous utilisez le compilateur interactif C #
csi
:Vous pouvez également déclarer des variables locales en lecture seule au
.csx
format script.la source
message
n'est pas une variable ici, il est compilé dans un champ. Ce n'est pas compliqué car la distinction existe également clairement dans le C # interactif:int x; Console.WriteLine(x)
est du C # interactif légal (parce quex
c'est un champ et implicitement initialisé) maisvoid foo() { int x; Console.WriteLine(x); }
ne l'est pas (parce quex
c'est une variable et utilisée avant d'être assignée). En outre,Expression<Func<int>> y = x; ((MemberExpression) y.Body).Member.MemberType
révélera quex
c'est vraiment un champ et non une variable locale.c # a déjà une variable en lecture seule, bien que dans une syntaxe quelque peu différente:
Considérez les lignes suivantes:
Comparer avec:
Certes, la première solution pourrait éventuellement être moins de code à écrire. Mais le 2ème extrait rendra la lecture seule explicite, lors du référencement de la variable.
la source
readonly var im = new List<string>(); im.Add("read-only variable, mutable object!");
.utilisez le
const
mot-clé pour créer une variable en lecture seule.référence: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/const
la source
const
où la variable ne peut être affectée que lors de son initialisation - pas par le style csharpconst
où seules les expressions au moment de la compilation peuvent être utilisées. Par exemple, vous ne pouvez pas faireconst object c = new object();
mais unreadonly
local vous le permettrait.Je pense que c'est parce qu'une fonction qui a une variable en lecture seule peut ne jamais être appelée, et il y a probablement quelque chose à ce sujet qui sort du cadre, et quand en auriez-vous besoin?
la source