c# - variable - static vs const




Statique readonly vs const (10)

J'ai lu autour de const et static readonly champs en static readonly . Nous avons quelques classes qui ne contiennent que des valeurs constantes. Utilisé pour diverses choses dans notre système. Donc je me demande si mon observation est correcte:

Est-ce que ce genre de valeurs constantes doit toujours être static readonly pour tout ce qui est public? Et seulement utiliser const pour les valeurs internes / protégées / privées?

Que recommandez-vous? Est-ce que je devrais peut-être même ne pas utiliser static readonly champs static readonly , mais plutôt utiliser des propriétés?


Const: Const n'est rien d'autre que "constant", une variable dont la valeur est constante mais au moment de la compilation. Et il est obligatoire de lui attribuer une valeur. Par défaut, un const est statique et nous ne pouvons pas changer la valeur d'une variable const tout au long du programme.

Static ReadOnly: une valeur de variable de type Static Readonly peut être affectée lors de l'exécution ou affectée lors de la compilation et modifiée lors de l'exécution. Mais la valeur de cette variable ne peut être modifiée que dans le constructeur statique. Et ne peut pas être changé plus loin. Il ne peut changer qu'une seule fois à l'exécution

Référence: c-sharpcorner


Ceci est juste un complément aux autres réponses. Je ne vais pas les répéter (maintenant quatre ans plus tard).

Il y a des situations où un const et un non-const ont une sémantique différente. Par exemple:

const int y = 42;

static void Main()
{
  short x = 42;
  Console.WriteLine(x.Equals(y));
}

imprime True , alors que:

static readonly int y = 42;

static void Main()
{
  short x = 42;
  Console.WriteLine(x.Equals(y));
}

écrit False .

La raison en est que la méthode x.Equals a deux surcharges, une qui prend un short ( System.Int16 ) et une qui prend un object ( System.Object ). Maintenant, la question est de savoir si l'un ou les deux s'appliquent avec mon argument y .

Lorsque y est une constante à la compilation (literal), le cas const , il devient important qu'il existe une conversion implicite d' int à short condition que l' int soit une constante et que le compilateur C # vérifie que sa valeur est comprise dans la gamme d'un short (qui 42 est). Voir Conversions d'expressions constantes implicites dans la spécification de langage C #. Donc les deux surcharges doivent être considérées. La surcharge Equals(short) est préférée (tout short est un object , mais tous les object sont pas short ). Donc y est converti en short , et cette surcharge est utilisée. Ensuite, Equals compare deux valeurs short identiques, ce qui donne true .

Lorsque y n'est pas une constante, aucune conversion implicite d' int en short n'existe. En effet, en général, un int peut être trop grand pour tenir dans un short . (Une conversion explicite existe, mais je n'ai pas dit Equals((short)y) , donc ce n'est pas pertinent.) Nous voyons qu'une seule surcharge s'applique, la valeur Equals(object) . Donc y est encadré pour object . Puis Equals va comparer un System.Int16 à un System.Int32 , et puisque les types d'exécution ne sont même pas d'accord, cela donnera false .

Nous concluons que dans certains cas (rares), changer un membre de type const en un static readonly (ou dans l'autre sens, quand cela est possible) peut changer le comportement du programme.


Il existe une différence mineure entre les champs conston et static readonly dans C # .Net

const doit être initialisé avec value 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 plus tard. Il ne peut pas être utilisé avec tous les types de données. Pour ex-DateTime. Il ne peut pas être utilisé avec le type de données DateTime.

public const DateTime dt = DateTime.Today;  //throws compilation error
public const string Name = string.Empty;    //throws compilation error
public static readonly string Name = string.Empty; //No error, legal

readonly peut être déclaré statique, mais pas nécessaire. Pas besoin de s'initialiser au moment de la déclaration. Sa valeur peut être affectée ou modifiée en utilisant le constructeur une fois. Il y a donc une possibilité de changer la valeur du champ readonly une fois (peu importe, s'il est statique ou non), ce qui n'est pas possible avec const.


J'utiliserais static readonly si le consommateur est dans un assemblage différent. Avoir le const et le consommateur dans deux assemblées différentes est une belle façon de se tirer une balle dans le pied .


Les champs publics en lecture seule sont un peu inhabituels; Les propriétés statiques publiques (avec seulement un get ) seraient plus communes (peut-être sauvegardées par un champ readonly statique privé).

Les valeurs de Const sont brûlées directement dans le site d'appel; c'est double tranchant:

  • il est inutile si la valeur est récupérée à l'exécution, peut-être à partir de la configuration
  • si vous changez la valeur d'un const, vous devez reconstruire tous les clients
  • mais ça peut être plus rapide, car cela évite un appel de méthode ...
  • ... qui peut parfois avoir été inline par le JIT de toute façon

Si la valeur ne changera jamais , alors const est bien - Zero etc font des consts raisonnables ;-p En dehors de cela, les propriétés statiques sont plus communes.


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 initialisés lorsque vous les déclarez d'abord comme une constante, mais ils sont généralement initialisés lors de la construction de l'objet dans le constructeur.

Ils ne peuvent pas être modifiés après l'initialisation, dans les conditions mentionnées ci-dessus.

Statique en lecture seule me semble un mauvais choix puisque, si c'est statique et ça ne change jamais, alors utilisez le public const, si ça peut changer alors ce n'est pas une constante et ensuite, selon vos besoins, vous pouvez soit utiliser read -seulement ou juste 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!


Quelques autres choses

const int a

  • doit être initialisé
  • l'initialisation doit être au moment de la compilation

readonly int un

  • peut utiliser la valeur par défaut, sans initialiser
  • l'initialisation peut être au moment de l'exécution

Un champ en lecture seule statique est avantageux lors de l'exposition à d'autres assemblages d'une valeur qui pourrait changer dans une version ultérieure.

Par exemple, supposons que l'assemblage X expose une constante comme suit:

public const decimal ProgramVersion = 2.3;

Si l'assembly Y référence X et utilise cette constante, la valeur 2.3 sera cuite dans l'ensemble Y lors de la compilation. Cela signifie que si X est recompilé plus tard avec la constante définie sur 2.4, Y utilisera toujours l'ancienne valeur de 2.3 jusqu'à ce que Y soit recompilé. Un champ statique en lecture seule évite ce problème.

Une autre façon de voir cela est que toute valeur qui pourrait changer dans le futur n'est pas constante par définition, et ne devrait donc pas être représentée comme telle.


const:

  1. valeur devrait être donnée lors de la déclaration
  2. compiler la constante de temps

lecture seulement:

  1. La valeur peut être donnée lors de la déclaration ou pendant l'exécution en utilisant des constructeurs. La valeur peut varier selon le constructeur utilisé.
  2. durée d'exécution constante

Lecture statique seulement : La valeur peut être modifiée par le constructeur statique à l'exécution. Mais pas à travers la fonction membre.

Constante : Par défaut statique. La valeur ne peut pas être changé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 à travers la fonction membre.

Vous pouvez jeter un oeil à mon repo: les types de propriété C # .





constants