Existe-t-il une différence entre les variables private const et private readonly en C #?

StackOverflow https://stackoverflow.com/questions/410723

  •  03-07-2019
  •  | 
  •  

Question

Existe-t-il une différence entre une variable private const et une variable private statique en lecture seule en C # (autre que l'obligation d'attribuer le const une expression de compilation)?

Comme elles sont toutes les deux privées, il n’ya pas de lien avec d’autres bibliothèques. Cela ferait-il une différence? Peut-il faire une différence de performance par exemple? Des chaînes internées? Quelque chose de similaire?

Était-ce utile?

La solution

Eh bien, vous pouvez utiliser des consts dans les attributs, car ils existent au moment de la compilation. Vous ne pouvez pas prédire la valeur d'une variable statique en lecture seule, car .cctor pourrait l'initialiser à partir de la configuration, etc.

En termes d’utilisation, les constantes sont gravées dans le code appelant. Cela signifie que si vous recompilez une dll bibliothèque pour modifier une constante publique , mais ne changez pas les consommateurs, ceux-ci utiliseront toujours la valeur d'origine. Cela ne se produira pas avec une variable en lecture seule. À l’inverse, les constantes sont (très, très légèrement) plus rapides, car elles ne font que charger la valeur (au lieu de devoir la dé-référencer).

Re interning; bien que vous puissiez le faire manuellement, il s'agit le plus souvent d'une fonctionnalité de compilation / exécution de littéraux; si vous initiez un champ en lecture seule via un littéral:

someField = "abc";

alors le "abc" sera interné. Si vous le lisez à partir de config, ça ne le sera pas. Dans la mesure où une chaîne constante doit être un littéral, elle sera également internée, mais l'accès est différent: encore une fois, la lecture du champ est une dé-référence, plutôt qu'un ldstr .

Autres conseils

En effet, les deux types ne peuvent pas être modifiés après leur initialisation, mais il existe quelques différences entre eux:

  • 'const' doit être initialisé à l'endroit où ils sont déclarés (au moment de la compilation), alors que 'readonly' peut être initialisé à l'endroit où il est déclaré ou à l'intérieur du constructeur (ar runtime).

Par exemple, const pourrait être utilisé dans cette situation:

public class MathValues
{
  public const double PI = 3.14159;
}

Et en lecture seule serait préférable pour ce cas:

public class Person
{
    public readonly DateTime birthDate;

    public Person(DateTime birthDate)
    {
        this.birthDate = birthDate;
    }
}

ou

public class Person
{
    public readonly DateTime birthDate = new DateTime(1986, 1, 24);
}
  • 'const' est statique, il est donc partagé entre toutes les instances de cette classe et est accessible directement (comme MathValues.PI), alors que 'readonly' n'est pas statique. En conséquence, une déclaration comme "static const" est illégale car const est statique, mais "static readonly" est légale

  • 'const' ne peut contenir que du type entier (sbyte, octet, short, ushort, int, uint, long, ulong, char, float, double, decimal, bool ou string), une énumération ou référence à null (pas des classes ou des structures car elles sont initialisées à l'exécution, avec le mot clé 'new'), alors que 'readonly' peut contenir des types, des structures ou des classes complexes (en utilisant le nouveau mot clé à l'initialisation) mais ne peut pas contenir d'énumérations

Il est important de noter que les constantes sont réellement stockées dans votre exécutable. Par conséquent, en déclarer beaucoup augmentera la taille de votre fichier exécutable.

Normalement, ce n’est pas un gros problème, mais un de mes amis a travaillé pour une société qui appliquait un "tout doit être constant". règle et a réussi à augmenter considérablement leur taille d’exécutable compilé.

Voici les différences entre les champs C # .NET const , en lecture seule et les champs en lecture seule (à partir de cet article ).

Constantes :

  • Statique par défaut
  • Doit avoir une valeur au moment de la compilation (c'est-à-dire que vous pouvez avoir "A" + "B" mais vous ne pouvez pas avoir d'appels de méthode)
  • Peut être utilisé dans les attributs
  • sont copiés dans chaque assemblage qui les utilise (chaque assemblage reçoit une copie locale des valeurs)
  • Pourrait être déclaré dans les fonctions

Champs d'instance en lecture seule :

  • Sont évalués lorsque l'instance est créée
  • Doit avoir défini la valeur avant la sortie du constructeur

Champs statiques en lecture seule :

  • Sont évalués lorsque l'exécution de code atteint la référence de classe (c'est-à-dire qu'une nouvelle instance est créée ou qu'une méthode statique est exécutée)
  • Doit avoir évalué la valeur au moment où le constructeur statique est terminé
  • Vous ne voulez vraiment pas placer ThreadStaticAttribute sur ceux-ci (car le constructeur statique sera exécuté dans un seul thread et définira la valeur de son thread; tous les autres threads auront cette valeur non initialisée)

Il existe une différence notable entre les champs const et en lecture seule dans C # .Net

.

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

en lecture seule peut être déclaré statique, mais pas nécessaire. Pas besoin d'initialiser au moment de la déclaration. Sa valeur peut être assignée ou modifiée en utilisant le constructeur. Donc, cela donne un avantage lorsqu'il est utilisé comme membre de classe d'instance. Deux instanciations différentes peuvent avoir une valeur différente du champ en lecture seule. Par exemple -

class A
{
    public readonly int Id;

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

Ensuite, le champ en lecture seule peut être initialisé avec des valeurs spécifiques instantanées, comme suit:

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

Ici, l'instance objOne aura la valeur du champ en lecture seule 5 et l'objTwo en a 10. Ce qui n'est pas possible avec const.

En cours d'utilisation? Pas vraiment. Les consts sont évalués à la compilation, alors que readonly est évalué à l'exécution. Vous pouvez également affecter une valeur en lecture seule à une valeur dans le constructeur.

Une dernière chose. Je n'ai pas vu cela dans les commentaires ci-dessus, même si je l'ai peut-être manqué. Vous ne pouvez pas créer de tableau constant.

private const int[] values = new int[] { 1, 2, 3 };

Mais vous pouvez le créer à l'aide d'un champ statique en lecture seule.

private static readonly int[] values = new int[] { 1, 2, 3 };

Ainsi, si vous avez besoin d'une constante de tableau, telle qu'une liste de valeurs autorisées, et qu'une énumération ne serait pas appropriée, la lecture statique en lecture seule est la seule solution. Par exemple, si le tableau contient des entiers nuls, comme ceci:

private static readonly int?[] values = new int?[] { null, 1, 2, 3 };

Vous ne pouvez pas faire cela avec une constante, n'est-ce pas?

La différence est que la valeur d'un champ statique en lecture seule est définie à l'exécution et peut donc être modifiée par la classe qui le contient, alors que la valeur d'un champ const est définie sur une constante de temps de compilation.

Dans le cas statique en lecture seule, la classe contenante est autorisée à la modifier uniquement

dans la déclaration de variable (via un initialiseur de variable) dans le constructeur statique (constructeurs d'instance, si ce n'est pas statique) static readonly est généralement utilisé si le type du champ n'est pas autorisé dans une déclaration const ou si la valeur n'est pas connue au moment de la compilation.

Les champs d'instance en lecture seule sont également autorisés.

N'oubliez pas que pour les types de référence, dans les deux cas (statique et instance), le modificateur readonly vous empêche uniquement d'attribuer une nouvelle référence au champ. En particulier, il ne rend pas immuable l'objet pointé par la référence.

class Program

{

  public static readonly Test test = new Test();

  static void Main(string[] args)

  {

     test.Name = "Program";

     test = new Test(); // Error: A static readonly field cannot be assigned to (except in a static constructor or a variable initializer)

  }

}

class Test

{

   public string Name;

}

La différence est que statique en lecture seule peut être modifié par la classe qui le contient, mais const ne peut jamais être modifié et doit être initialisé avec une constante de temps de compilation. Pour développer un peu le cas statique en lecture seule, la classe qui le contient ne peut que le modifier:

- dans la déclaration de variable (via un initialiseur de variable).

- dans le constructeur statique (constructeurs d'instance si ce n'est pas statique).

Mot clé Const en C # .NET

Exemple: chaîne publique const abc = “xyz”; Initialisé uniquement à la déclaration. La valeur est évaluée lors de la compilation et ne peut pas être modifiée lors de l'exécution. Toute tentative de modification entraînera une erreur de compilation. Const est déjà un peu statique. Les classes et les structures étant initialisées au moment de l’exécution avec un nouveau mot clé, vous ne pouvez pas définir de constante sur une classe ou une structure. Mais, il doit être l'un des types intégraux. Mot-clé en lecture seule dans C # .NET

Exemple: chaîne publique en lecture seule abc; Peut être initialisé dans un code de déclaration ou un code de consturateur. La valeur est évaluée au moment de l'exécution. Peut être déclaré en tant qu'attribut statique ou d'instance. Un champ en lecture seule peut contenir un objet complexe en utilisant le nouveau mot-clé au moment de l'exécution.

Les champs en lecture seule peuvent être initialisés soit au niveau de la déclaration , soit dans un constructeur de la classe . Par conséquent, les champs en lecture seule peuvent avoir des valeurs différentes selon le constructeur utilisé .

Un membre en lecture seule peut également être utilisé pour les constantes d'exécution , comme dans l'exemple suivant:

public static readonly uint currentTicks = (uint)DateTime.Now.Ticks;

Les champs en lecture seule ne sont pas implicitement statiques. Par conséquent, le mot clé statique peut (doit) être appliqué explicitement à un champ en lecture seule, si nécessaire. Ceci n'est pas autorisé pour les champs const, qui sont implicitement statiques.

Les membres

en lecture seule peuvent contenir des objets complexes à l’aide du nouveau mot clé à l’initialisation .

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