J'ai lu environ const
et static readonly
champs. Nous avons certaines classes qui ne contiennent que des valeurs constantes. Utilisé pour diverses choses dans notre système. Je me demande donc si mon observation est correcte:
Ce type de valeurs constantes devrait-il toujours s'appliquer static readonly
à tout ce qui est public? Et utiliser uniquement const
pour les valeurs internes / protégées / privées?
Que recommandez-vous? Dois-je peut-être même ne pas utiliser de static readonly
champs, mais plutôt utiliser des propriétés?
static readonly
: essayez d'utiliser un const à l'intérieur d'unIEnumerator
qui déclencherait une irrécupérableyield
et vous obtiendrez une "erreur de compilation interne" redoutée . Je n'ai pas testé le code en dehors d'Unity3D, mais j'espère qu'il s'agit d'un bug mono ou .NET . C'est néanmoins un problème c # .static readonly
ne peut pas être utilisé dans l'switch-case
instruction commecase
variable,const
est requis à cet effet.static readonly
ne peut pas être utilisé aussi comme paramètre d'attributRéponses:
public static readonly
les champs sont un peu inhabituels;public static
les propriétés (avec seulement unget
) seraient plus courantes (peut-être soutenues par unprivate static readonly
champ).const
les valeurs sont gravées directement dans le site d'appel; c'est à double tranchant:Si la valeur ne changera jamais , alors const est bien -
Zero
etc faire des consts raisonnables; p En dehors de cela, lesstatic
propriétés sont plus courantes.la source
readonly
champs ne peuvent pas être utilisés dans les instructions switch / case, mais vous en avez besoinconst
.J'utiliserais
static readonly
si le consommateur est dans un assemblage différent. Avoir leconst
et le consommateur dans deux assemblages différents est une bonne façon de se tirer une balle dans le pied .la source
internal const
ou enpublic static readonly
fonction de la visibilité souhaitée.public const
(par exemple, tout ce qui fait partie d'une norme. Chaque fois que je travaille avec XML, il y a un fichier d'espaces de noms avec un tas depublic const string
.) Mais en général,public const
ne doit être utilisé qu'après avoir considéré les implications correctement.Peu de choses plus pertinentes à noter:
const int a
en lecture seule dans un
la source
ctor
seul.Ceci n'est qu'un complément aux autres réponses. Je ne les répéterai pas (maintenant quatre ans plus tard).
Il y a des situations où a
const
et un non-const ont une sémantique différente. Par exemple:s'imprime
True
alors que:écrit
False
.La raison en est que la méthode
x.Equals
a deux surcharges, une qui prend unshort
(System.Int16
) et une qui prend unobject
(System.Object
). Maintenant, la question est de savoir si l'un ou les deux s'appliquent à mony
argument.Quand
y
est une constante de temps de compilation (littéral), leconst
cas, il devient important qu'il existe une conversion implicite de àint
àshort
condition que l'int
est une constante, et à condition que le compilateur C # vérifie que sa valeur est dans la plage de ashort
( qui42
est). Voir Conversions implicites d'expression constante dans la spécification du langage C #. Il faut donc tenir compte des deux surcharges. La surchargeEquals(short)
est préférable (toutshort
est unobject
, mais tous neobject
sontshort
). Soy
est converti enshort
, et cette surcharge est utilisée.Equals
Compare ensuite deuxshort
de valeur identique, et cela donnetrue
.Lorsque
y
n'est pas une constante, aucune conversion implicite deint
àshort
n'existe. En effet, en général, unint
peut être trop énorme pour tenir dans unshort
. (Une conversion explicite existe, mais je n'ai pas ditEquals((short)y)
, donc ce n'est pas pertinent.) Nous voyons qu'une seule surcharge s'applique, celle-Equals(object)
là.y
Est donc encadréobject
. Ensuite,Equals
va comparer unSystem.Int16
à unSystem.Int32
, et puisque les types d'exécution ne sont même pas d'accord, cela donnerafalse
.Nous concluons que dans certains cas (rares), le changement d'un
const
membre de type enstatic readonly
champ (ou dans l'autre sens, lorsque cela est possible) peut changer le comportement du programme.la source
short x = 42;
légale. Parce que là, vous avez unint
, à savoir le littéral42
, qui est implicitement transformé enshort x
. Mais alors, ils auraient pu limiter cela à des littéraux uniquement numériques; cependant, ils ont choisi d'autoriser également des choses commeshort x = y;
oùy
est défini commeconst int y = 42;
, puis ils se sont retrouvés avec cela.Une chose à noter est que const est limité aux types primitifs / valeur (à l'exception des chaînes)
la source
const
pourrait également être utilisé pour d'autres types, sauf qu'il doit être initialisé à null, ce qui le rend inutile :)System.Exception
? :)const
peuvent être utilisés, sontsbyte
,byte
,short
,ushort
,int
,uint
,long
,ulong
,char
,float
,double
,decimal
,bool
, plus tous lesenum
types.const
ne peut pas être utilisé pour d'autres types de valeurs, commeDateTime
ouTimeSpan
ouBigInteger
. Il ne peut pas non plus être utilisé pour laIntPtr
structure (considéré comme un type "primitif" par certains; le terme type primitif prête à confusion en C #). ↵↵ Leconst
peut être utilisé pour tous les types de référence . Si le type eststring
, n'importe quelle valeur de chaîne peut être spécifiée. Sinon, la valeur doit êtrenull
.const
utilisantdefault
. Pour lesstruct
types, il s'agit d'une instance avec tous ses membres définis sur les valeurs par défaut.Statique en lecture seule : la valeur peut être modifiée via le
static
constructeur lors de l'exécution. Mais pas via la fonction membre.Constante : par défaut
static
. La valeur ne peut pas être modifiée de n'importe où (Ctor, Function, runtime etc no-where).Lecture seule : la valeur peut être modifiée via le constructeur lors de l'exécution. Mais pas via la fonction membre.
Vous pouvez consulter mes types de propriétés repo: C # .
la source
Le
readonly
mot-clé est différent duconst
mot - clé. Unconst
champ ne peut être initialisé qu'à la déclaration du champ. Unreadonly
champ peut être initialisé soit à la déclaration, soit dans un constructeur. Par conséquent, lesreadonly
champs peuvent avoir des valeurs différentes selon le constructeur utilisé. De plus, même si unconst
champ est une constante de compilation, lereadonly
champ peut être utilisé pour les constantes d'exécutionRéférence MSDN courte et claire ici
la source
const
etreadonly
sont similaires, mais ils ne sont pas exactement les mêmes.Un
const
champ est une constante au moment de la compilation, ce qui signifie que cette valeur peut être calculée au moment de la compilation. Unreadonly
champ permet des scénarios supplémentaires dans lesquels du code doit être exécuté lors de la construction du type. Après la construction, unreadonly
champ ne peut pas être modifié.Par exemple, les
const
membres peuvent être utilisés pour définir des membres comme:Puisque les valeurs comme 3.14 et 0 sont des constantes au moment de la compilation. Cependant, considérez le cas où vous définissez un type et souhaitez en fournir des instances préfabriquées. Par exemple, vous souhaiterez peut-être définir une classe Color et fournir des "constantes" pour les couleurs courantes comme le noir, le blanc, etc. On pourrait le faire avec des membres statiques réguliers:
Mais alors, rien n'empêche un client de Color de s'en occuper, peut-être en échangeant les valeurs Noir et Blanc. Inutile de dire que cela provoquerait la consternation pour les autres clients de la classe Color. La fonctionnalité "en lecture seule" résout ce scénario.
En introduisant simplement le
readonly
mot - clé dans les déclarations, nous préservons l'initialisation flexible tout en empêchant le code client de contourner.Il est intéressant de noter que les membres const sont toujours statiques, alors qu'un membre en lecture seule peut être statique ou non, tout comme un champ normal.
Il est possible d'utiliser un seul mot-clé à ces deux fins, mais cela entraîne des problèmes de version ou des problèmes de performances. Supposons un instant que nous ayons utilisé un seul mot-clé pour cela (const) et un développeur a écrit:
et un développeur différent a écrit du code qui s'appuyait sur A:
Maintenant, le code généré peut-il s'appuyer sur le fait que AC est une constante de temps de compilation? C'est-à-dire, l'utilisation de AC peut-elle simplement être remplacée par la valeur 0? Si vous dites "oui" à cela, cela signifie que le développeur de A ne peut pas changer la façon dont AC est initialisé - cela lie les mains du développeur de A sans autorisation.
Si vous dites «non» à cette question, une optimisation importante est manquée. L'auteur de A est peut-être certain que AC sera toujours nul. L'utilisation de const et readonly permet au développeur de A de spécifier l'intention. Cela permet un meilleur comportement de version et également de meilleures performances.
la source
Ma préférence est d'utiliser const chaque fois que je le peux, ce qui, comme mentionné ci-dessus, est limité aux expressions littérales ou à quelque chose qui ne nécessite pas d'évaluation.
Si je me heurte à cette limitation, je retombe en statique uniquement , avec une mise en garde. J'utiliserais généralement une propriété statique publique avec un getter et un champ privé statique en lecture seule comme Marc le mentionne ici .
la source
Référence: c-sharpcorner
la source
Un champ en lecture seule statique est avantageux lors de l'exposition à d'autres assemblys d'une valeur qui pourrait changer dans une version ultérieure.
Par exemple, supposons que l'assembly
X
expose une constante comme suit:Si l'assembly
Y
référenceX
et utilise cette constante, la valeur 2.3 sera intégrée à l'assemblyY
lors de la compilation. Cela signifie que siX
est recompilé plus tard avec la constante définie à 2,4,Y
utilisera toujours l'ancienne valeur de 2,3 jusqu'à ce qu'ilY
soit recompilé. Un champ en lecture seule statique évite ce problème.Une autre façon de voir les choses est que toute valeur qui pourrait changer à l'avenir n'est pas constante par définition, et ne devrait donc pas être représentée comme une seule.
la source
const:
lecture seulement:
la source
Const : les valeurs des variables const doivent être définies avec la déclaration et après cela, elles ne changeront pas. const sont implicitement statiques, donc sans créer d'instance de classe, nous pouvons y accéder. cela a une valeur au moment de la compilation
ReadOnly : valeurs de variable en lecture seule que nous pouvons définir tout en déclarant ainsi qu'en utilisant le constructeur lors de l'exécution. les variables en lecture seule ne peuvent pas accéder sans instance de classe.
Static readonly : valeurs de variables statiques en lecture seule que nous pouvons définir tout en déclarant ainsi que par le biais d'un constructeur statique mais pas avec tout autre constructeur.Ces variables sont également accessibles sans créer d'instance de classe (en tant que variables statiques).
la lecture statique seule sera un meilleur choix si nous devons consommer les variables dans différents assemblages.Veuillez vérifier les détails complets dans le lien ci-dessous
https://www.stum.de/2009/01/14/const-strings-a-very-convenient-way-to-shoot-yourself-in-the-foot/
la source
Il existe une différence mineure entre les champs const et statiques en lecture seule dans C # .Net
const doit être initialisé avec une valeur au moment de la compilation.
const est par défaut statique et doit être initialisé avec une valeur constante, qui ne peut pas être modifiée ultérieurement. Il ne peut pas être utilisé avec tous les types de données. Par exemple DateTime. Il ne peut pas être utilisé avec le type de données DateTime.
readonly peut être déclaré comme statique, mais pas nécessaire. Pas besoin d'initialiser au moment de la déclaration. Sa valeur peut être attribuée ou modifiée à l'aide du constructeur une fois. Il y a donc une possibilité de changer une fois la valeur du champ en lecture seule (peu importe, s'il est statique ou non), ce qui n'est pas possible avec const.
la source
Les constantes sont comme le nom l'indique, les champs qui ne changent pas et sont généralement définis statiquement au moment de la compilation dans le code.
Les variables en lecture seule sont des champs qui peuvent changer dans des conditions spécifiques.
Ils peuvent être soit initialisés lorsque vous les déclarez pour la première fois comme une constante, mais ils sont généralement initialisés lors de la construction de l'objet à l'intérieur du constructeur.
Ils ne peuvent pas être modifiés après l'initialisation, dans les conditions mentionnées ci-dessus.
La lecture statique seule me semble un mauvais choix car, si elle est statique et qu'elle ne change jamais, utilisez-la simplement public const, si elle peut changer, ce n'est pas une constante, puis, selon vos besoins, vous pouvez soit utiliser read -seulement ou simplement une variable régulière.
En outre, une autre distinction importante est qu'une constante appartient à la classe, tandis que la variable en lecture seule appartient à l'instance!
la source
Un const (étant déterminé au moment de la compilation) peut être utilisé dans les cas où une statique en lecture seule ne peut pas, comme dans les instructions switch ou les constructeurs d'attribut. En effet, les champs en lecture seule ne sont résolus qu'au moment de l'exécution et certaines constructions de code nécessitent une assurance de temps de compilation. Une statique en lecture seule peut être calculée dans un constructeur, ce qui est souvent une chose essentielle et utile. La différence est fonctionnelle, comme devrait l'être leur utilisation à mon avis.
En termes d'allocation de mémoire, au moins avec les chaînes (étant un type de référence), il ne semble pas y avoir de différence dans la mesure où les deux sont internés et référenceront la seule instance internée.
Personnellement, ma valeur par défaut est statique en lecture seule, car elle a plus de sens sémantique et logique pour moi, d'autant plus que la plupart des valeurs ne sont pas nécessaires au moment de la compilation. Et, en passant, la statique publique en lecture seule n'est pas inhabituelle ou rare du tout comme l'indique la réponse marquée: par exemple,
System.String.Empty
est un.la source
Une autre différence entre déclarer const et statique en lecture seule réside dans l'allocation de mémoire.
Un champ statique appartient au type d'un objet plutôt qu'à une instance de ce type. Par conséquent, une fois que la classe est référencée pour la première fois, le champ statique "vivra" dans la mémoire pour le reste du temps et la même instance du champ statique sera référencée par toutes les instances du type.
En revanche, un champ const "appartient à une instance du type.
Si la mémoire de désallocation est plus importante pour vous, préférez utiliser const . Si la vitesse, alors utilisez statique en lecture seule .
la source