Quelle est la différence entre const et readonly?

Quelle est la différence entre const et readonly et utilisez-vous l'un sur l'autre?

1035
demandé sur Praveen 2008-09-11 12:02:19
la source

30 ответов

mis à part la différence apparente de

  • devant déclarer la valeur au moment de la définition d'une const VS readonly les valeurs peuvent être calculées dynamiquement mais doivent être attribuées avant la sortie du constructeur.. après cela, il est gelé.
  • 'const sont implicitement static . Vous utilisez une notation ClassName.ConstantName pour y accéder.

il y a une différence subtile. Considérons une classe définie dans AssemblyA .

public class Const_V_Readonly
{
  public const int I_CONST_VALUE = 2;
  public readonly int I_RO_VALUE;
  public Const_V_Readonly()
  {
     I_RO_VALUE = 3;
  }
}

AssemblyB fait référence à AssemblyA et utilise ces valeurs dans le code. Quand ceci est compilé,

  • dans le cas de la valeur const , il est comme une find-replace, la valeur 2 est "cuit dans" le AssemblyB IL. Cela signifie que si demain je vais mettre à jour I_CONST_VALUE à 20 dans le futur. AssemblyB aurait encore 2 jusqu'à ce que je le recompiler .
  • dans le cas de la valeur readonly , il est comme un ref à un emplacement de mémoire. La valeur n'est pas cuite dans l'IL de AssemblyB . Cela signifie que si l'emplacement de la mémoire est mis à jour, AssemblyB obtient la nouvelle valeur sans recompilation. Donc si I_RO_VALUE est mis à jour à 30, vous n'avez besoin que de construire AssemblyA . Tous les clients n'ont pas besoin d'être recompilé.

donc si vous êtes sûr que la valeur de la constante ne sera pas changer l'utilisation d'un const .

public const int CM_IN_A_METER = 100;

mais si vous avez une constante qui peut changer (par ex. R. T. précision).. en cas de doute, utilisez un readonly .

public readonly float PI = 3.14;

mise à Jour: Aku besoins pour obtenir une mention coz il l'a souligné en premier. J'ai aussi besoin de brancher où j'ai appris ça.. Effective C# - Bill Wagner

1016
répondu Gishu 2015-09-22 11:01:23
la source

Il y a un piège avec consts! Si vous faites référence à une constante d'une autre assemblée, sa valeur sera compilée directement dans l'Assemblée appelante. De cette façon, lorsque vous mettez à jour la constante dans l'ensemble référencé, elle ne change pas dans l'ensemble appelant!

242
répondu aku 2014-04-10 19:53:37
la source

constantes

  • les constantes sont statiques par défaut
  • ils doivent avoir une valeur au moment de la compilation (vous pouvez par exemple avoir 3.14 * 2, mais ne pouvez pas appeler les méthodes)
  • pourrait être déclaré dans les fonctions
  • sont copiés dans chaque assemblage qui les utilise (chaque assemblage obtient une copie locale des valeurs)
  • peut être utilisé dans les attributs

Readonly champs d'instance

  • Doit avoir la valeur de consigne, le temps que le constructeur sort
  • sont évalués lors de la création de l'instance

Static readonly fields

  • sont évalués lorsque l'exécution du code atteint la référence de classe (lorsque la nouvelle instance est créée ou qu'une méthode statique est exécutée)
  • doit avoir une valeur évaluée au moment où le constructeur statique est fait
  • il n'est pas recommandé de mettre ThreadStaticAttribute sur ceux-ci (les constructeurs statiques seront exécutés dans un seul thread et définiront la valeur pour son thread; tous les autres threads auront cette valeur non initialisée)
127
répondu splattne 2011-06-09 16:03:30
la source

Juste pour ajouter, En lecture seule pour les types référence ne fait que la référence readonly pas les valeurs. Par exemple:

public class Const_V_Readonly
{
  public const int I_CONST_VALUE = 2;
  public readonly char[] I_RO_VALUE = new Char[]{'a', 'b', 'c'};

  public UpdateReadonly()
  {
     I_RO_VALUE[0] = 'V'; //perfectly legal and will update the value
     I_RO_VALUE = new char[]{'V'}; //will cause compiler error
  }
}
50
répondu 2008-09-30 01:19:13
la source

cela explique . Résumé: const doit être initialisé au moment de la déclaration, readonly peut être initialisé sur le constructeur (et donc avoir une valeur différente selon le constructeur utilisé).

EDIT: See Gotcha gishu's above for the subtle difference""

36
répondu Vinko Vrsalovic 2008-09-11 13:52:22
la source

const : ne peut être changé nulle part.

readonly : cette valeur ne peut être modifiée que par le constructeur. Ne peut pas être changé dans les fonctions normales.

25
répondu Deepthi 2013-11-28 02:04:55
la source

il y a un petit gotcha avec readonly. Un champ readonly peut être défini plusieurs fois dans le(s) constructeur (s). Même si la valeur est définie dans deux différents constructeurs enchaînés, elle est quand même autorisée.


public class Sample {
    private readonly string ro;

    public Sample() {
        ro = "set";
    }

    public Sample(string value) : this() {
        ro = value; // this works even though it was set in the no-arg ctor
    }
}
22
répondu Mike Two 2008-10-20 02:14:57
la source

un membre constant est défini au moment de la compilation et ne peut pas être modifié au moment de l'exécution. Les constantes sont déclarées comme un champ, en utilisant le mot-clé const et doivent être initialisées comme elles sont déclarées.

public class MyClass
{
    public const double PI1 = 3.14159;
}

Un readonly membre est comme une constante en ce qu'il représente une valeur immuable. La différence est qu'un membre readonly peut être initialisé à l'exécution, dans un constructeur, ainsi que d'être initialisé comme ils sont déclarés.

public class MyClass1
{
     public readonly double PI2 = 3.14159;

     //or

     public readonly double PI3;

     public MyClass2()
     {
         PI3 = 3.14159;
     }
}

const

  • ils ne peuvent pas être déclarés comme static (ils sont implicitement statiques)
  • la valeur de constante est évaluée au moment de la compilation
  • les constantes sont initialisées à la déclaration seulement

readonly

  • ils peuvent être au niveau de l'instance ou statique
  • la valeur est évaluée au temps d'exécution
  • ne peut être initialisé que par une déclaration ou un code dans le constructeur
20
répondu Sujit 2016-04-28 02:05:21
la source

un const est une constante de temps de compilation alors que readonly permet de calculer une valeur à l'exécution et de la régler dans le constructeur ou le Field initializer. Ainsi, un 'const' est toujours constant mais 'readonly' est lu-seulement une fois qu'il est assigné.

Eric Lippert de l'équipe C#, a plus d'informations sur les différents types de l'immuabilité

19
répondu Wheelie 2008-09-11 12:07:46
la source

voici un autre lien démontrant comment la version de const n'est pas sûre, ou pertinente pour les types de référence.

résumé :

  • la valeur de votre propriété const est définie au moment de la compilation et ne peut pas changer au moment de l'exécution
  • Const ne peut pas être marqué comme statique - le mot-clé indique qu'ils sont statiques, contrairement aux champs readonly qui peuvent.
  • Const ne peut pas être rien, sauf de la valeur (primitive) de types
  • Le mot clé readonly marque le champ immuable. Cependant la propriété peut être changée à l'intérieur du constructeur de la classe
  • le mot-clé readonly only peut également être combiné avec static pour le faire agir de la même manière qu'un const (atleast sur la surface). Il y a une différence marquée lorsque vous regardez L'IL entre les deux
  • const les champs sont marqués comme "littéral" dans IL tandis que readonly est "initonly"
14
répondu Chris S 2014-12-01 19:33:29
la source

encore un autre gotcha: les valeurs readonly peuvent être changées par le code "devious" via la réflexion.

var fi = this.GetType()
             .BaseType
             .GetField("_someField", 
                       BindingFlags.Instance | BindingFlags.NonPublic);
fi.SetValue(this, 1);

puis-je changer un champ privé hérité readonly en C# en utilisant la réflexion?

8
répondu Greg 2017-05-23 14:54:59
la source

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

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

8
répondu Yeasin Abedin Siam 2016-01-12 20:42:57
la source

je crois qu'une valeur const est la même pour tous les objets (et doit être initialisée avec une expression littérale), alors que readonly peut être différent pour chaque instanciation...

5
répondu Daren Thomas 2008-09-11 12:03:46
la source

l'un des membres de l'équipe de notre Bureau a fourni les directives suivantes sur le moment d'utiliser const, static, et readonly:

  • Utiliser const quand vous avez une variable d'un type que vous pouvez connaître au moment de l'exécution (un littéral de chaîne, int, double, les énumérations...) que vous voulez que toutes les instances ou les consommateurs d'une classe aient accès à où la valeur ne devrait pas changer.
  • utilisez statique lorsque vous avez des données qui vous voulez toutes les instances ou les consommateurs d'une classe à avoir accès à l'endroit où la valeur peut changer.
  • Utiliser static readonly quand vous avez une variable d'un type que vous ne pouvez pas savoir au moment de l'exécution (objets) que vous souhaitez toutes les instances ou les consommateurs d'une classe à avoir accès à l'endroit où la valeur ne doit pas changer.
  • Utiliser readonly quand vous avez une instance de niveau variable, vous saurez au moment de la création de l'objet cela ne devrait pas changer.

Une dernière remarque: const champ est statique, mais l'inverse n'est pas vrai.

5
répondu Scott Lawrence 2008-10-03 00:43:37
la source

ils sont tous les deux constants, mais un const est également disponible au moment de la compilation. Cela signifie que l'un des aspects de la différence est que vous pouvez utiliser des variables const comme entrée pour attribuer des constructeurs, mais pas seulement des variables readonly.

exemple:

public static class Text {
  public const string ConstDescription = "This can be used.";
  public readonly static string ReadonlyDescription = "Cannot be used.";
}

public class Foo 
{
  [Description(Text.ConstDescription)]
  public int BarThatBuilds {
    { get; set; }
  }

  [Description(Text.ReadOnlyDescription)]
  public int BarThatDoesNotBuild {
    { get; set; }
  }
}
5
répondu Hallgrim 2016-01-08 02:44:00
la source

les Variables marquées const ne sont guère plus que des macros #define fortement dactylographiées, au moment de la compilation les références des variables const sont remplacées par des valeurs littérales inline. En conséquence, seuls certains types de valeurs primitives peuvent être utilisés de cette manière. Les Variables marquées "readonly" peuvent être définies, dans un constructeur, à l'exécution et leur "read-only-ness" est également appliqué à l'exécution. Il y a des coûts de performance mineurs associés à cela, mais cela signifie que vous pouvez utiliser readonly avec n'importe quel type (même types de référence).

de plus, les variables const sont intrinsèquement statiques, alors que les variables readonly peuvent être spécifiques à une instance si on le souhaite.

4
répondu Wedge 2009-01-06 01:34:33
la source

le mot clé readonly est différent du mot clé const. Const champ ne peut être initialisé à la déclaration du champ. Un champ readonly peut être initialisé soit dans la déclaration soit 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 comme dans l'exemple suivant:

public static readonly uint l1 = (uint) DateTime.Now.Ticks;
4
répondu Nitish Kakkar 2013-06-13 22:15:04
la source

le readonly mot clé est différent du const mot clé. Un champ const ne peut être initialisé qu'à la déclaration de ce champ. Un champ en lecture seule peut être initialisé soit à la déclaration 151990920 "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 const est un temps de compilation constante, le readonly champ peut être utilisé pour runtime constantes comme dans l'exemple suivant:

public static readonly uint timeStamp = (uint)DateTime.Now.Ticks;
4
répondu Yas 2015-12-12 21:12:48
la source

l'Autre gotcha .

Puisque const ne fonctionne vraiment qu'avec les types de données de base, si vous voulez travailler avec une classe, vous pouvez vous sentir "forcé" d'utiliser ReadOnly. Cependant, attention au piège! ReadOnly signifie que vous ne pouvez pas remplacer l'objet avec un autre objet (vous ne pouvez pas faire référence à un autre objet). Mais tout processus qui a une référence à l'objet est libre de modifier les valeurs à l'intérieur l' objet!

Alors ne soyez pas confus en pensant que cela implique Qu'un utilisateur ne peut pas changer les choses. Il n'est pas simple de syntaxe en C# pour empêcher l'instanciation d'une classe d'avoir ses valeurs internes changé (autant que je sache).

3
répondu Mark T 2008-09-17 17:28:01
la source

il y a une différence notable entre les champs const et readonly dans C#.Net

const est par défaut statique et doit être initialisé avec une valeur constante, qui ne peut pas être modifié plus tard. Le changement de valeur n'est pas autorisé dans les constructeurs, trop. 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 readonly string Name = string.Empty; //No error, legal

ne peut être déclaré que comme statique, mais pas nécessaire. Pas besoin d'initialiser au moment de la déclaration. Sa valeur peut être assignée ou changée en utilisant le constructeur. Ainsi, il donne l'avantage quand il est utilisé comme membre de la classe d'instance. Deux instanciations différentes peuvent avoir une valeur différente du champ readonly. Pour ex -

class A
{
    public readonly int Id;

    public A(int i)
    {
        Id = i;
    }
}

alors le champ readonly peut être initialisé avec des valeurs spécifiques instantanées, comme suit:

A objOne = new A(5);
A objTwo = new A(10);

ici, l'exemple objOne aura la valeur du champ readonly comme 5 et objTwo a 10. Ce qui n'est pas possible en utilisant const.

3
répondu Chirag 2014-12-15 16:01:10
la source

une constante sera compilée dans le consommateur sous la forme d'une valeur littérale tandis que la chaîne statique servira de référence à la valeur définie.

comme un exercice, essayez de créer une bibliothèque externe et consommez-la dans une application de console, puis Modifier les valeurs dans la bibliothèque et recompiler (sans recompiler le programme de consommateur), laisser tomber la DLL dans le répertoire et exécuter l'EXE manuellement, vous devriez trouver que la chaîne constante ne change pas.

2
répondu Brett Ryan 2009-09-08 16:52:20
la source

constante

nous devons fournir la valeur au champ const lorsqu'elle est définie. Le compilateur enregistre alors la valeur de la constante dans les métadonnées de l'assemblage. Cela signifie qu'une constante ne peut être définie que pour le type primitif comme booléen, char, byte et ainsi de suite. Les constantes sont toujours considérées comme des membres statiques, pas des membres d'instance.

Readonly

Readonly fields ne peuvent être résolus au moment de l'exécution. Cela signifie que nous pouvons définir une valeur pour une valeur à l'aide du constructeur pour le type dans lequel le champ est déclaré. La vérification est faite par le compilateur à qui les champs readonly ne sont pas écrits par une autre méthode que le constructeur.

plus sur les deux expliqué ici dans cet article

2
répondu Vikram 2015-08-04 08:34:27
la source

principalement; Vous pouvez attribuer une valeur à un champ statique en lecture seule à une valeur non constante à l'exécution, alors qu'une const doit se voir attribuer une valeur constante.

1
répondu ljs 2009-09-08 16:24:24
la source

Un const doit être "151930920 codées" en dur , où readonly peut-être défini dans le constructeur de la classe.

1
répondu Greg 2011-02-20 15:29:26
la source

Const et readonly sont similaires, mais ils ne sont pas exactement les mêmes. Const champ est une constante 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 en lecture seule ne peut pas être modifié.

par exemple, les membres const peuvent être utilisés pour définir des membres comme:

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

puisque des valeurs comme 3.14 et 0 sont des constantes 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 = r;
        green = g;
        blue = b;
    }
}

mais il n'y a rien pour garder un client de couleur d'en faire tout un plat, 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 la flexibilité de l'initialisation tout en empêchant le code client de tourner en rond.

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 = r;
        green = g;
        blue = 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 un instant que nous avons utilisé un seul mot-clé pour cela (const) et un développeur a écrit:

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

et un autre développeur a écrit un code qui s'est appuyé sur un:

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

maintenant, le code qui est généré peut-il reposer sur le fait que A. C est une constante 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 raté. 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. Ce permet un meilleur comportement de version et aussi une meilleure performance.

1
répondu Ramesh Rajendran 2013-09-28 12:19:52
la source

ReadOnly :La valeur sera initialisé qu'une seule fois depuis le constructeur de la classe.

const: peut être initialisé dans n'importe quelle fonction mais seulement une fois

1
répondu donstack 2014-01-24 11:34:17
la source

la différence est que la valeur d'un champ statique en lecture seule est définie au temps d'exécution, de sorte qu'il peut avoir une valeur différente pour différentes exécutions du programme. Cependant, la valeur d'un champ const est fixée à une constante de temps de compilation.

Rappelez-vous: Pour les types de référence, dans les deux cas (statique et instance), le modificateur readonly ne vous empêche d'attribuer une nouvelle référence au champ. Elle ne rend pas immuable l'objet pointé du doigt par référence.

pour plus de détails, veuillez consulter la Foire Aux Questions sur ce sujet.: http://blogs.msdn.com/csharpfaq/archive/2004/12/03/274791.aspx

1
répondu Yonatan Nir 2014-04-05 18:39:18
la source
Les variables constantes

sont déclarées et initialisées au moment de la compilation. La valeur ne peut pas être changé après les pupilles. Les variables en lecture seule seront initialisées uniquement à partir du constructeur statique de la classe. Lecture seule est utilisée uniquement lorsque l'on veut affecter la valeur au moment de l'exécution.

1
répondu Omar AMEZOUG 2015-04-10 00:09:25
la source

const champ ne peut être initialisé à la déclaration du champ. Un champ readonly peut être initialisé soit dans la déclaration soit dans un constructeur.

1
répondu Geka P 2016-03-22 16:20:37
la source

Une chose à ajouter à ce que les gens ont dit ci-dessus. Si vous avez un ensemble contenant une valeur readonly (par exemple readonly MaxFooCount = 4;), Vous pouvez changer la valeur que l'appel d'assemblages voir en envoyant une nouvelle version de cet assemblage avec une valeur différente (par exemple readonly MaxFooCount = 5;)

mais avec un const, il serait plié dans le code de l'appelant quand l'appelant a été compilé.

si vous avez atteint ce niveau de compétence, vous sont prêts pour le Livre de Bill Wagner, efficace C#: 50 façons spécifiques d'améliorer votre C# Qui répond à cette question en détail, (et 49 autres choses).

0
répondu Anthony 2008-09-15 14:14:17
la source

Autres questions sur c# .net constants const readonly