Static readonly vs const

j'ai lu des articles sur les champs const et static readonly . Nous avons quelques classes qui ne contiennent que des valeurs constantes. Utilisé pour différentes choses dans notre système. Je me demande donc si mon observation est correcte:

ces valeurs constantes devraient-elles toujours être static readonly pour tout ce qui est public? Et n'utiliser const que pour les valeurs internes/protégées/privées?

que recommandez-vous? Devrais-je peut-être même pas utiliser static readonly , mais plutôt utiliser des propriétés peut-être?

1219
demandé sur John Saunders 2009-04-16 15:21:43

15 réponses

Les champs

public static readonly sont un peu inhabituels; les propriétés public static (avec seulement un get ) seraient plus courantes (peut-être appuyées par un champ private static readonly ).

const les valeurs sont gravées directement dans le site d'appel; c'est à double tranchant:

  • il est inutile si la valeur est extraite au moment de l'exécution, peut-être de config
  • si vous changez la valeur d'un const, vous devez reconstruire tous les clients
  • mais il peut être plus rapide, car il évite un appel de méthode...
  • ...qui peut parfois avoir été Intim é par le JIT de toute façon

si la valeur va jamais changer, puis const est amende - Zero etc faire consts raisonnables ;P autre que cela, static propriétés sont plus courantes.

841
répondu Marc Gravell 2018-06-24 04:58:30

j'utiliserais static readonly si le consommateur est dans un assemblage différent. Avoir le const et le consommateur dans deux assemblages différents est une belle façon de tirer vous-même dans le pied .

206
répondu Michael Stum 2016-12-25 16:50:58

autres choses

const int a

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

readonly int a

  • peut utiliser la valeur par défaut, sans initialiser
  • initialisation peut être au moment de l'exécution
176
répondu Peter 2013-05-10 17:04:12

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ù 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 , tandis 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 .

quand y est une constante de temps de compilation (littérale), le cas const , il devient important qu'il existe une conversion implicite de int à short pourvu que le int soit une constante, et à condition que le compilateur C# vérifie que sa valeur est dans la gamme d'un short (qui 42 est). Voir conversion D'expressions constantes implicites dans la spécification C# Language. Il faut donc tenir compte de ces deux surcharges. La surcharge Equals(short) est préférée (toute short est une object , mais toutes les object ne sont pas short ). Donc y est converti en short , et cette surcharge est utilisée. Puis Equals compare deux short de valeur identique, et qui donne true .

lorsque y n'est pas une constante, il n'existe pas de implicite conversion de int en short . C'est parce qu'en général un int peut être trop énorme pour entrer 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'un seul de surcharge s'applique, le Equals(object) un. Donc y est boxé en object . Alors Equals va comparer un System.Int16 à un System.Int32 , et puisque les types de course-TIME ne sont même pas d'accord, qui donnera false .

nous concluons que dans certains cas (rares), changer un membre de type const en un champ static readonly (ou de l'autre façon, lorsque cela est possible) peut changer le comportement du programme.

157
répondu Jeppe Stig Nielsen 2017-09-13 13:30:01

Une chose à noter est const est limité aux primitive/types de valeur (à l'exception des chaînes de caractères)

83
répondu Chris S 2009-04-16 11:28:51

le mot-clé readonly est différent du mot-clé const . Un champ const ne peut être initialisé qu'à la déclaration du champ. Un champ readonly peut être initialisé à la déclaration ou dans un constructeur. Par conséquent, les champs readonly peuvent avoir des valeurs différentes selon le constructeur utilisé. En outre, alors qu'un champ const est une constante de temps de compilation, le champ readonly peut être utilisé pour les constantes d'exécution

référence MSDN courte et claire ici

23
répondu yazanpro 2012-11-14 18:58:37

Statique Lecture Seule : La valeur peut être changée par l'intermédiaire du constructeur static à l'exécution. Mais pas par la fonction de membre.

Constante : Par défaut static . La valeur ne peut être changée de n'importe où (Ctor, Function, runtime etc no-where).

Lire Seulement : La valeur peut être changée par le constructeur à l'exécution. Mais pas par la fonction de membre.

Vous pouvez avoir un coup d'oeil à mon repo : C# types de propriété .

17
répondu Yeasin Abedin Siam 2018-06-24 04:59:23

const et readonly sont similaires, mais ils ne sont pas exactement les mêmes.

un champ const est une constante de temps de compilation, ce qui signifie que cette valeur peut être calculée au moment de la compilation. Un champ readonly permet des scénarios supplémentaires dans lesquels un certain code doit être exécuté pendant la construction du type. Après la construction, un champ readonly ne peut pas être modifié.

par exemple, const peut être utilisé pour définir membres comme:

struct Test
{
    public const double Pi = 3.14;
    public const int Zero = 0;
}

puisque les valeurs comme 3.14 et 0 sont des constantes de temps de compilation. Cependant, considérez le cas où vous définissez un type et voulez fournir quelques exemples pré-fab de celui-ci. Par exemple, vous pourriez vouloir définir une classe de couleur et fournir des "constantes" pour les couleurs communes comme le noir, Le Blanc, etc. Il n'est pas possible de le faire avec const membres, comme la droite, ne sont pas des constantes de compilation. On pourrait le faire avec des membres statiques réguliers:

public class Color
{
    public static Color Black = new Color(0, 0, 0);
    public static Color White = new Color(255, 255, 255);
    public static Color Red   = new Color(255, 0, 0);
    public static Color Green = new Color(0, 255, 0);
    public static Color Blue  = new Color(0, 0, 255);
    private byte red, green, blue;

    public Color(byte r, byte g, byte b) => (red, green, blue) = (r, g, b);
}

mais alors il n'y a rien pour empêcher un client de couleur de mucking avec elle, peut-être en échangeant les valeurs Noir et blanc. Inutile de dire que cela causerait de la consternation pour les autres clients de la classe de couleur. La fonction" en lecture seule " traite de ce scénario.

en introduisant simplement le mot-clé readonly dans les déclarations, nous préservons l'initialisation flexible tout en empêchant le code client de mucking around.

public class Color
{
    public static readonly Color Black = new Color(0, 0, 0);
    public static readonly Color White = new Color(255, 255, 255);
    public static readonly Color Red   = new Color(255, 0, 0);
    public static readonly Color Green = new Color(0, 255, 0);
    public static readonly Color Blue  = new Color(0, 0, 255);
    private byte red, green, blue;

    public Color(byte r, byte g, byte b) => (red, green, blue) = (r, g, b);
}

Il est intéressant de noter que const membres sont toujours statiques, alors qu'un membre readonly peut être soit statique ou non, comme un champ.

il est possible d'utiliser un seul mot-clé pour ces deux fins, mais cela conduit soit à des problèmes de versioning ou des problèmes de performance. Supposons pour un moment que nous avons utilisé un seul mot-clé pour ce (const) et un développeur a écrit:

public class A
{
    public static const C = 0;
}

et un développeur différent code écrit qui s'appuie sur A:

public class B
{
    static void Main() => Console.WriteLine(A.C);
}

maintenant, le code généré peut-il se fier au fait que A. c est une constante de temps de compilation? C'est-à-dire: l'utilisation de A. C peut-elle simplement être remplacée par la valeur 0? Si vous dites " oui " à ceci, alors cela signifie que le développeur de A ne peut pas changer la façon dont A. c est initialisé -- cela lie les mains du développeur de A sans permission.

Si vous dites "non" à cette question alors important d'optimisation est manquée. Peut-être que L'auteur de A est positif que A. C sera toujours zéro. L'utilisation de const et readonly permet au développeur de spécifier l'intention. Cela permet un meilleur comportement de version et aussi de meilleures performances.

13
répondu Ramesh Rajendran 2018-06-24 05:01:48

Ma préférence est d'utiliser const chaque fois que je peux, ce qui comme mentionné ci-dessus est limité à des expressions littérales ou quelque chose qui ne nécessite pas d'évaluation.

si je m'élève contre cette limitation, alors je retombe à statique readonly , avec une mise en garde. J'utiliserais généralement une propriété statique publique avec un getter et un support statique privée en lecture seule champ comme Marc mentionne ici .

11
répondu Peter Meyer 2017-05-23 12:18:26

un champ statique en lecture seule est avantageux lors de l'exposition à autres assemblages 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 assemblage Y référence X et utilise cette constante, la valeur 2.3 sera cuit dans l'assemblage Y une fois compilé. Cela signifie que si X est recompilé plus tard avec la constante mis à 2.4, "151920920 reste" utiliser l'ancienne valeur de 2,3 jusqu'à ce que Y est recompilé. Statique readonly field évite ce problème.

une Autre façon de voir c'est que toute valeur qui peut le changement dans l'avenir n'est pas constant par définition, et devrait donc ne pas être représentée comme une seule personne.

6
répondu Yagnesh Cangi 2015-04-07 13:44:22

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

statique en lecture seule: une valeur D'une variable statique en lecture seule peut être assignée à l'exécution ou assignée au moment de la compilation et changée à Runtime. Mais cette valeur ne peut être modifiée 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

6
répondu mayank 2015-12-24 11:30:26

const:

  1. valeur à indiquer sur la déclaration
  2. compiler time constant

readonly:

  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 dépendent du constructeur utilisé.
  2. constante de temps d'exécution
3
répondu dasumohan89 2013-12-11 11:28:25

il y a une différence mineure entre les champs const et static readonly 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é plus tard. Il ne peut pas être utilisé avec tous les types de données. Pour l'ex - DateTime. Il ne peut pas être utilisé avec DateTime datatype.

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

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

2
répondu Chirag 2014-12-15 13:06:45
Les constantes

sont comme le nom implique, 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 pour la première fois comme une constante, mais habituellement ils sont initialisés lors de la construction de l'objet à l'intérieur du constructeur.

ils ne peuvent pas être changés après le l'initialisation a lieu, dans les conditions mentionnées ci-dessus.

statique en lecture seule sonne comme un mauvais choix pour moi car, si elle est statique et il ne change jamais, donc il suffit de l'utiliser public const, si elle peut changer alors ce n'est pas une constante et puis, selon vos besoins, vous pouvez soit utiliser en lecture seule ou juste une variable régulière.

Aussi, une autre distinction importante est qu'une constante appartient à la classe, tandis que la lecture seule variable appartient à la exemple!

1
répondu Claudiu Cojocaru 2016-11-21 22:49:32

Const : les valeurs variables de const doivent définir avec la déclaration et après cela il ne changera pas. const sont implicitement statiques donc sans créer d'instance de classe nous pouvons y accéder. cette valeur a une valeur au moment de la compilation

ReadOnly : valeurs readonly variables que nous pouvons définir tout en déclarant ainsi qu'en utilisant le constructeur à l'exécution. readonly variables ne peut pas accéder sans instance de classe.

statique readonly : valeurs statiques readonly variables que nous pouvons définir tout en déclarant ainsi que seulement par le biais de constructeur statique, mais pas avec tout autre constructeur.ces variables sont également accessibles sans créer d'instance de classe (comme variables statiques).

statique readonly sera un meilleur choix si nous devons consommer les variables dans des assemblages différents.Veuillez vérifier les détails dans le lien ci-dessous

https://www.stum.de/2009/01/14/const-strings-a-very-convenient-way-to-shoot-yourself-in-the-foot /

0
répondu user1756922 2018-09-27 15:57:48