Question Quelle est la différence entre const et readonly?


Quelle est la différence entre const et readonly et en utilisez-vous un plutôt que l'autre?


989
2017-09-11 08:02


origine


Réponses:


En dehors de la différence apparente de

  • devoir déclarer la valeur au moment de la définition d'un const CONTRE readonly les valeurs peuvent être calculées dynamiquement mais doivent être assignées avant que le constructeur ne se termine. après cela, il est gelé.
  • 'const sont implicitement static. Vous utilisez un ClassName.ConstantName notation 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 les références AssemblyA et utilise ces valeurs dans le code. Quand cela est compilé,

  • dans le cas de const valeur, c'est comme un find-replace, la valeur 2 est "cuite" dans le AssemblyBde 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 recompile.
  • dans le cas de readonly valeur, c'est comme un ref à un emplacement de mémoire. La valeur n'est pas cuite dans AssemblyBde IL. 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, il vous suffit de construire AssemblyA. Tous les clients n'ont pas besoin d'être recompilés.

Donc, si vous êtes sûr que la valeur de la constante ne changera pas, utilisez un const.

public const int CM_IN_A_METER = 100;

Mais si vous avez une constante qui peut changer (par exemple, w.r.t. précision) .. ou en cas de doute, utilisez un readonly.

public readonly float PI = 3.14;

Mise à jour: Aku doit obtenir une mention car il l'a signalé en premier. Aussi j'ai besoin de brancher là où j'ai appris ça .. Effectif C # - Bill Wagner


979
2017-09-11 08:24



Il y a un gotcha avec consts! Si vous référencez une constante d'un autre assembly, sa valeur sera compilée directement dans l'assembly appelant. De cette façon, lorsque vous mettez à jour la constante dans l'assembly référencé, elle ne changera pas dans l'assembly appelant!


237
2017-09-11 08:15



Constantes

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

En lecture seule les champs d'instance

  • Doit avoir une valeur définie, au moment où le constructeur quitte
  • Sont évalués lors de la création de l'instance

Champs statiques en lecture seule

  • Sont évalués lorsque l'exécution du code atteint la référence de la classe (lorsqu'une 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 terminé
  • Il n'est pas recommandé d'y ajouter ThreadStaticAttribute (les constructeurs statiques seront exécutés dans un seul thread et définiront la valeur de son thread, tous les autres threads auront cette valeur non initialisée)

125
2017-12-02 11:50



Juste pour ajouter, ReadOnly pour les types de référence ne fait que la référence en lecture seule et non 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
  }
}

48
2017-09-11 10:37



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

EDIT: Voir Gotcha Gishu ci-dessus pour la différence subtile


37
2017-09-11 08:04



const: Ne peut être modifié nulle part.

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


25
2018-05-21 13:21



Il y a un petit gotcha avec readonly. Un champ en lecture seule peut être défini plusieurs fois dans le (s) constructeur (s). Même si la valeur est définie dans deux constructeurs chaînés différents, elle est toujours 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
    }
}

20
2017-10-19 22:14



Un const est une constante à la compilation alors que readonly permet de calculer une valeur à l'exécution et de l'initialiser dans le constructeur ou dans le champ. Donc, un 'const' est toujours constant mais 'readonly' est en lecture seule une fois qu'il est assigné.

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


19
2017-09-11 08:07



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 const mot-clé et doit être initialisé comme ils sont déclarés.

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

UNE readonly Le membre est comme une constante en ce sens qu'il représente une valeur immuable. La différence est que readonly Le membre peut être initialisé au moment de l'exécution, dans un constructeur, tout en pouvant être initialisé au fur et à mesure qu'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

lecture seulement

  • Ils peuvent être au niveau de l'instance ou statiques
  • La valeur est évaluée au moment de l'exécution
  • readonly peut être initialisé dans la déclaration ou par le code dans le constructeur

19
2017-09-17 11:48