Question

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

Était-ce utile?

La solution

En dehors de la différence apparente de

  • avoir à déclarer la valeur au moment de la définition d'une const VS readonly les valeurs peuvent être calculées de manière dynamique, mais doit être attribué avant que le constructeur ne sort..après cela, il est gelé.
  • 'const sont implicitement static.Vous utilisez un ClassName.ConstantName la 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 références AssemblyA et utilise ces valeurs dans le code.Lorsque cela est compilé,

  • dans le cas de la const la valeur, c'est comme un rechercher-remplacer, la valeur 2 est "cuit dans" l' AssemblyBs 'IL.Cela signifie que si, demain, je vais mettre à jour I_CONST_VALUE à 20 ans dans le futur. AssemblyB aurait encore 2 jusqu'à ce que je le recompiler.
  • dans le cas de la readonly la valeur, c'est comme un ref à un emplacement de mémoire.La valeur n'est pas cuit dans des AssemblyBs 'IL.Cela signifie que si l'emplacement de mémoire est mis à jour, AssemblyB devient la nouvelle valeur sans recompilation.Donc, si I_RO_VALUE est mise à jour à 30, vous avez seulement besoin 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 change pas d'utiliser un const.

public const int CM_IN_A_METER = 100;

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

public readonly float PI = 3.14;

Mise à jour:Aku besoins pour obtenir une mention coz il l'a souligné en premier.Aussi j'ai besoin de plug où j'ai appris ce.. Efficace C# - Projet De Loi De Wagner

Autres conseils

Il y a un piège avec consts!Si vous faites référence à une constante à partir d'une autre assemblée, sa valeur sera compilé à droite dans la convocation de l'assemblée.De cette façon, lorsque vous mettez à jour la constante dans l'assembly référencé, il ne changera pas dans la convocation de l'assemblée!

Constantes

  • Les constantes sont statiques par défaut
  • Ils doivent avoir une valeur lors de la compilation en temps (vous pouvez avoir par exemple3.14 * 2, mais ne peut pas appeler des méthodes)
  • Pourrait être déclarée à l'intérieur des fonctions
  • Sont copiés dans chaque assemblée qui les utilise (chaque assemblée obtient une copie locale de valeurs)
  • Peut être utilisé dans les attributs

Readonly champs d'instance

  • Doit avoir la valeur définie, par le temps constructeur sorties
  • Sont évaluées lors de l'instance est créée

Static readonly champs

  • Sont évaluées lors de l'exécution de code à coups de référence de classe (lors de la nouvelle instance est créée ou une méthode statique est exécuté)
  • Doit avoir une valeur évaluée par le temps que le constructeur statique est fait
  • Il n'est pas recommandé de mettre ThreadStaticAttribute sur chacun de ces constructeurs statiques sera exécutée dans un thread uniquement et sera mis à la valeur de son fil;tous les autres threads aura cette valeur non initialisée)

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
  }
}

Ceci explique cela.Résumé:const doit être initialisé au moment de la déclaration, en lecture seule peuvent être initialisés dans le constructeur (et donc avoir une valeur différente selon le constructeur utilisé).

EDIT:Voir uasin gishu gotcha ci-dessus pour la subtile différence

const:Ne peut pas être changé n'importe où.

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

Il y a une petite chose à corriger avec readonly.Un readonly champ peut être défini à plusieurs reprises dans le constructeur(s).Même si la valeur est définie dans deux différents enchaîné les constructeurs, il est encore permis.


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
    }
}

Une constante membre est défini au moment de la compilation et ne peut pas être modifiée lors de l'exécution.Les constantes sont déclarées comme un champ, à l'aide de la const mot-clé et doit être initialisé 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 readonly le membre peut être initialisée lors de l'exécution, dans un constructeur, comme le bien-être pu être initialisé comme elles sont déclarées.

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 statique)
  • La valeur de la constante est évaluée au moment de la compilation
  • les constantes sont initialisés à la déclaration

readonly

  • Ils peuvent être soit au niveau de l'instance ou statique
  • La valeur est évaluée au moment de l'exécution
  • en lecture seule peuvent être initialisés dans une déclaration ou par le code dans le constructeur

Const est une constante de compilation alors qu'en lecture seule permet à une valeur calculée au moment de l'exécution et défini dans le constructeur ou le champ d'initialiseur.Donc, un "const" est toujours constante, mais 'readonly' est en lecture seule une fois qu'il est attribué.

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

Voici un autre lien en démontrant comment const n'est pas la version coffre-fort, ou pertinents pour les types référence.

Résumé:

  • La valeur de votre const propriété est définie au moment de la compilation et ne peut pas être modifiée à l'exécution
  • Const ne peut pas être marqués comme statique - le mot-clé indique qu'ils sont statiques, à la différence des champs en lecture seule qui peut.
  • Const ne peut pas être n'importe quoi sauf de la valeur (primitive) types
  • Le mot clé readonly marque le champ immuable.Toutefois, la propriété peut être modifiée à l'intérieur du constructeur de la classe
  • Le readonly que le mot peut aussi être combiné avec de l'électricité statique à la faire agir de la même manière comme un const (au moins sur la surface).Il existe une différence marquée lorsque vous regardez le IL entre les deux
  • const champs sont marqués comme "littérale" en IL tout en readonly est "initonly"

Lecture Seule :La valeur peut être modifiée par Ctor au moment de l'exécution.Mais pas à travers la Fonction de membre

Constant :Par défaut statique.La valeur ne peut pas être modifié à partir de n'importe où ( Ctor, la Fonction d'exécution etc n'-où)

Encore une autre chose à corriger:readonly valeurs peuvent être modifiées par "sournois" code via la réflexion.

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

Puis-je modifier une private readonly hérité de domaine en C# à l'aide de la réflexion?

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

L'un des membres de l'équipe de notre bureau a fourni les indications suivantes sur l'utilisation de const, statique, et en lecture seule:

  • Utilisation const lorsque vous disposez d'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 souhaitez toutes les instances ou les consommateurs d'une classe à avoir accès à l'endroit où la valeur ne doit pas changer.
  • Utilisation statique lorsque vous avez des données que vous souhaitez toutes les instances ou les consommateurs d'une classe à avoir accès à l'endroit où la valeur peut changer.
  • Utilisation static readonly lorsque vous disposez d'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.
  • Utilisation readonly lorsque vous avez une instance de niveau variable, vous saurez au moment de la création de l'objet qui ne devrait pas changer.

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

Ils sont à la fois constante, mais un const est également disponible au moment de la compilation.Cela signifie que l'un des aspects de la différence, c'est que vous pouvez utiliser const variables en entrée d'attribuer les constructeurs, mais pas en lecture seule des variables.

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; }
  }
}

Les Variables marquées const sont un peu plus que fortement typé #définir des macros, au moment de la compilation variable const références sont remplacées en ligne des valeurs littérales.En conséquence seulement un certain nombre de primitives types de valeur peut être utilisé de cette façon.Les Variables marquées en lecture seule peut être définie, dans un constructeur, au moment de l'exécution et leur lecture seule-ness est appliquée au cours de l'exécution ainsi.Il y a quelques petites performances de coût associé à cette mais cela signifie que vous pouvez utiliser en lecture seule avec n'importe quel type (même les types de référence).

Aussi, const variables sont par nature statique, alors que la lecture seule des variables d'instance spécifique si vous le souhaitez.

Un autre gotcha.

Depuis const vraiment fonctionne uniquement avec les types de données de base, si vous voulez travailler avec une classe, vous pouvez vous sentir "obligé" d'utiliser En lecture seule.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 de l'objet!

Afin de ne pas les confondre en pensant que ReadOnly implique 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).

Il n'y a de différence notable entre const et readonly champs C#.Net

const est par défaut statique et doit être initialisé avec la valeur de la constante, qui ne peuvent pas être modifiés ultérieurement.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 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 readonly string Name = string.Empty; //No error, legal

en lecture seule peuvent être déclarées comme statique, mais pas nécessaire.Pas besoin d'initialiser au moment de la déclaration.Sa valeur peut être affecté ou modifié à l'aide de constructeur.Ainsi, il donne un avantage lorsqu'il est utilisé comme instance de la classe membre.Deux instanciation peut avoir des valeurs différentes de champ en lecture seule.Pour l'ex -

class A
{
    public readonly int Id;

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

Puis readonly champ peut être initialisé avec des instantanés de valeurs spécifiques, comme suit:

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

Ici, exemple objOne aura la valeur d'un champ en lecture seule comme 5 et objTwo a 10.Ce qui n'est pas possible à l'aide de const.

Une constante sera compilé dans le consommateur est une valeur littérale, alors que la statique de la chaîne va servir de référence à la valeur définie.

À titre d'exercice, essayez de créer une bibliothèque externe et de le consommer dans une application console, puis modifier les valeurs dans la bibliothèque et le recompiler (sans avoir à recompiler le programme des consommateurs), baisse de la DLL dans le répertoire et exécutez le fichier EXE manuellement, vous devriez trouver que la constante de chaîne ne change pas.

Constant

Nous avons besoin de fournir de la valeur à la const champ lorsqu'il est défini.Le compilateur enregistre ensuite la constante de valeur dans l'assemblée des métadonnées.Cela signifie qu'une constante peut être définie que pour les primitives de type boolean, char, byte, et ainsi de suite.Les constantes sont toujours considérés comme des membres statiques, pas les membres de l'instance.

Readonly

Readonly les champs 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 effectuée par le compilateur qui readonly champs ne sont pas écrites par toute autre méthode que le constructeur.

Plus sur les deux expliqué ici, dans cet article

CONST

  1. mot-clé const peut être appliquée à des champs ou des variables locales
  2. Nous devons assigner const champ au moment de la déclaration
  3. Pas de Mémoire Allouée à Cause const valeur est incorporée dans le code IL à lui-même après la compilation.C'est comme trouver toutes les occurrences de la variable const et de la remplacer par sa valeur.Ainsi, le code IL après la compilation aura valeurs codées en dur à la place des variables const
  4. Const en C# sont par défaut statique.
  5. La valeur est constante pour tous les objets
  6. Il est dll versioning problème, Ce qui signifie que chaque fois que nous changeons un public const variable ou une propriété , (En fait, il n'est pas censé être changé en théorie), toutes les autres dll ou d'assemblage qui utilise cette variable doit être re-construit
  7. Seulement C# types intégrés peuvent être déclarées comme constante
  8. Const champ ne peut pas être passé sous la ref ou paramètre de sortie

ReadOnly

  1. mot clé readonly s'applique uniquement aux champs qui ne sont pas des variables locales
  2. Nous pouvons attribuer readonly champ au moment de la déclaration ou dans le constructeur,pas dans les autres méthodes.
  3. dynamique de la mémoire allouée pour les champs en lecture seule qui nous permet d'obtenir la valeur au moment de l'exécution.
  4. Readonly appartient à l'objet créé, donc accessible par une seule instance de la classe.Pour en faire un membre de classe, nous devons ajouter un mot-clé static devant readonly.
  5. La valeur peut être différente en fonction constructeur utilisé (comme il appartient à un objet de la classe)
  6. Si vous déclarez un non-types primitifs (type de référence) en readonly seule référence est immuable pas l'objet qu'il contient.
  7. Puisque la valeur est obtenue au moment de l'exécution, il n'y a pas de dll problème de contrôle de version avec readonly champs/ propriétés.
  8. Nous pouvons passer readonly champ ref ou des paramètres dans le constructeur contexte.

Principalement;vous pouvez affecter une valeur à une static readonly champ à une non-valeur de la constante lors de l'exécution, alors qu'un const a attribué une valeur constante.

Un const doit être codé en dur, où que readonly peut être situé dans le constructeur de la classe.

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 en lecture seule permet à d'autres scénarios dans lesquels certains code doit être exécuté lors de la construction de ce type.Après la construction, un champ en lecture seule ne peuvent pas être modifiés.

Par exemple, const membres peuvent être utilisées pour définir les 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 compilation.Cependant, considérons le cas où vous définissez un type et souhaitez fournir certains pré-fab instances de celui-ci.E. g., vous pouvez définir une classe de Couleur et de fournir des "constantes" pour le commun des couleurs comme le Noir, 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 faire ça avec régulièrement des membres statiques:

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 alors il n'y a rien à garder un client de la Couleur de coucher avec elle, peut-être par permutation des valeurs Noires et Blanches.Inutile de dire que ce serait provoquer la consternation pour les autres clients de la classe de Couleur.Le "readonly" fonctionnalité répond à ce scénario.En introduisant simplement le mot clé readonly dans les déclarations, nous préserver de l'initialisation flexible, tout en empêchant le code client du nettoyage autour de.

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 pour ces deux fins, mais cela mène à une gestion des versions des problèmes ou des problèmes de performances.Supposons pour un instant que nous avons utilisé un seul mot-clé pour cette (const) et un développeur a écrit:

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

et un autre développeur a écrit le code qui reposait sur Une:

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

Maintenant, peut-on le code qui est généré compter sur le fait que A. C est une constante de compilation?I. e., l'utilisation de l'A. C tout simplement être remplacé par la valeur 0?Si vous dites "oui", alors cela signifie que le développeur de Un ne peut pas changer la façon dont A. C est initialisé -- ce liens entre les mains du développeur de Un sans sa permission.Si vous dites "non" à cette question alors important d'optimisation est raté.Peut-être l'auteur de l'Un est positif que A. C sera toujours zéro.L'utilisation de const et readonly permet au développeur de spécifier l'intention.Elle permet un meilleur comportement de contrôle de version et aussi de meilleures performances.

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 une seule fois

La différence est que la valeur d'un static readonly champ est défini au moment de l'exécution, de sorte qu'il peut avoir une valeur différente pour différentes exécutions du programme.Toutefois, la valeur d'un const champ est défini à la compilation constante de temps.

Souvenez-vous:Pour les types référence, dans les deux cas (statique et de l'instance), le readonly modificateur seulement vous empêche de l'attribution d'une nouvelle référence dans le domaine.Concrètement, il ne fait pas immuable de l'objet pointé par la référence.

Pour plus de détails, veuillez vous référer à la C# foire aux Questions sur ce sujet:http://blogs.msdn.com/csharpfaq/archive/2004/12/03/274791.aspx

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.Variables en lecture seule sera initialisé seulement à partir de la Statique, le constructeur de la classe.Lecture seule est utilisée uniquement lorsque l'on veut affecter la valeur au moment de l'exécution.

Une chose à ajouter à ce que les gens ont dit ci-dessus.Si vous avez un assemblage contenant un readonly valeur (par ex.readonly MaxFooCount = 4;), vous pouvez modifier la valeur d'appeler les assemblages de voir, par l'envoi d'une nouvelle version de cette assemblée, avec une valeur différente (par ex.readonly MaxFooCount = 5;)

Mais avec un const, il serait pliée en l'appelant du code lorsque l'appelant a été compilé.

Si vous avez atteint ce niveau de C# de compétence, vous êtes prêt pour le projet de Loi de Wagner livre, Efficace C#:50 Moyens Spécifiques pour Améliorer Votre C# Qui répond à cette question en détail, (et 49 autres choses).

La différence clé Const est le C équivalent de #DEFINE.Le nombre littéralement se substituer à la précompilateur.Readonly est effectivement traitée comme une variable.

Cette distinction est particulièrement pertinente lorsque vous avez Un Projet en fonction d'un Public constant de Projet B.Supposons que le public des changements constants.Maintenant, votre choix de const/readonly aura un impact sur le comportement sur le projet:

Const:le projet A ne pas attraper la nouvelle valeur (sauf si c'est recompilé avec la nouvelle const, bien sûr), parce qu'il a été compilé avec les constantes subtituted dans.

ReadOnly:Projet Une volonté de toujours demander à un projet B pour la valeur de la variable, donc il vous choisir jusqu'à la nouvelle valeur de la constante publique dans B.

Honnêtement, je vous recommande de l'utiliser en lecture seule pour près de tout, sauf vraiment les constantes universelles ( par ex.Pi, Inches_To_Centimeters).Pour tout ce qui pourrait peut-être changer, je dis que l'utilisation en lecture seule.

Espérons que cela aide, Alan.

Dans des mots simples, Const est le temps de compilation et readonly est le moment de l'exécution.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top