Quels sont les avantages d'avoir une variable membre déclarée en lecture seule? S'agit-il simplement d'une protection contre une modification de sa valeur pendant le cycle de vie de la classe ou l'utilisation de ce mot clé entraîne-t-elle des améliorations de vitesse ou d'efficacité?
295
readonly
champs de types de structure imposent une pénalité de performance par rapport aux champs mutables qui ne sont tout simplement pas mutés, car l'invocation de tout membre d'unreadonly
champ de type valeur obligera le compilateur à faire une copie du champ et à appeler le Le député là-dessus.Réponses:
Le
readonly
mot-clé est utilisé pour déclarer une variable membre constante, mais permet de calculer la valeur au moment de l'exécution. Cela diffère d'une constante déclarée avec leconst
modificateur, dont la valeur doit être définie au moment de la compilation. À l'aide de,readonly
vous pouvez définir la valeur du champ soit dans la déclaration, soit dans le constructeur de l'objet dont le champ est membre.Utilisez-le également si vous ne voulez pas avoir à recompiler les DLL externes qui référencent la constante (car elle est remplacée au moment de la compilation).
la source
Je ne pense pas qu'il y ait des gains de performances en utilisant un champ en lecture seule. Il s'agit simplement d'une vérification pour s'assurer qu'une fois l'objet entièrement construit, ce champ ne peut pas pointer vers une nouvelle valeur.
Cependant, "lecture seule" est très différent des autres types de sémantique en lecture seule car il est appliqué au moment de l'exécution par le CLR. Le mot clé en lecture seule se compile en .initonly qui est vérifiable par le CLR.
Le véritable avantage de ce mot-clé est de générer des structures de données immuables. Les structures de données immuables par définition ne peuvent pas être modifiées une fois construites. Cela permet de raisonner très facilement sur le comportement d'une structure lors de l'exécution. Par exemple, il n'y a aucun danger de passer une structure immuable à une autre portion aléatoire de code. Ils ne peuvent jamais le changer afin que vous puissiez programmer de manière fiable contre cette structure.
Voici une bonne entrée sur l'un des avantages de l'immuabilité: le filetage
la source
Il n'y a aucun avantage apparent en termes de performances à utiliser
readonly
, du moins aucun que je n'ai jamais vu mentionné nulle part. C'est juste pour faire exactement ce que vous suggérez, pour empêcher toute modification une fois qu'elle a été initialisée.Il est donc avantageux en ce qu'il vous aide à écrire du code plus robuste et plus lisible. Le véritable avantage de ce genre de choses vient lorsque vous travaillez en équipe ou pour la maintenance. Déclarer quelque chose comme
readonly
s'apparente à mettre un contrat pour l'utilisation de cette variable dans le code. Considérez-le comme l'ajout de documentation de la même manière que d'autres mots clés commeinternal
ouprivate
, vous dites "cette variable ne doit pas être modifiée après l'initialisation", et en plus vous l' appliquez .Donc, si vous créez une classe et marquez certaines variables membres
readonly
par conception, vous vous empêchez, vous-même ou un autre membre de l'équipe, de faire une erreur plus tard lorsqu'ils développent ou modifient votre classe. À mon avis, c'est un avantage qui vaut la peine (au détriment de la complexité supplémentaire de la langue, comme le mentionne doofledorfer dans les commentaires).la source
Pour le dire en termes très pratiques:
Si vous utilisez une const dans la dll A et la dll B référence cette const, la valeur de cette const sera compilée dans la dll B. Si vous redéployez la dll A avec une nouvelle valeur pour cette const, la dll B utilisera toujours la valeur d'origine.
Si vous utilisez un readonly dans les références dll A et dll B qui sont en lecture seule, ce readonly sera toujours recherché lors de l'exécution. Cela signifie que si vous redéployez la DLL A avec une nouvelle valeur pour cette lecture seule, la DLL DLL utilisera cette nouvelle valeur.
la source
const
gain de performances peut être supérieurreadonly
. Voici une explication un peu plus approfondie avec le code: dotnetperls.com/readonlyreadonly
champs. Vous ne pouvez pas stocker unnew object();
dans unconst
et cela a du sens car vous ne pouvez pas faire cuire des éléments sans valeur tels que des références dans d'autres assemblys pendant la compilation sans changer d'identité.Il existe un cas potentiel où le compilateur peut effectuer une optimisation des performances basée sur la présence du mot clé en lecture seule.
Cela ne s'applique que si le champ en lecture seule est également marqué comme statique . Dans ce cas, le compilateur JIT peut supposer que ce champ statique ne changera jamais. Le compilateur JIT peut en tenir compte lors de la compilation des méthodes de la classe.
Exemple typique: votre classe peut avoir un champ IsDebugLoggingEnabled statique en lecture seule qui est initialisé dans le constructeur (par exemple basé sur un fichier de configuration). Une fois que les méthodes réelles sont compilées JIT, le compilateur peut ommettre des parties entières du code lorsque la journalisation du débogage n'est pas activée.
Je n'ai pas vérifié si cette optimisation est réellement implémentée dans la version actuelle du compilateur JIT, il ne s'agit donc que de spéculations.
la source
Gardez à l'esprit que la lecture seule s'applique uniquement à la valeur elle-même, donc si vous utilisez un type de référence en lecture seule, la référence ne sera pas modifiée. L'état de l'instance n'est pas protégé par lecture seule.
la source
N'oubliez pas qu'il existe une solution de contournement pour obtenir les
readonly
champs définis en dehors de tout constructeur utilisant desout
paramètres.Un peu désordonné mais:
Plus de discussion ici: http://www.adamjamesnaylor.com/2013/01/23/Setting-Readonly-Fields-From-Chained-Constructors.aspx
la source
out
..Étonnamment, la lecture seule peut en fait entraîner un code plus lent, comme l'a découvert Jon Skeet lors du test de sa bibliothèque Noda Time. Dans ce cas, un test exécuté en 20 secondes n'a pris que 4 secondes après la suppression en lecture seule.
https://codeblog.jonskeet.uk/2014/07/16/micro-optimization-the-surprising-inefficiency-of-readonly-fields/
la source
readonly struct
en C # 7.2, l'avantage de rendre le champ non en lecture seule disparaît.Si vous avez une valeur prédéfinie ou pré-calculée qui doit rester la même tout au long du programme, vous devez utiliser constante, mais si vous avez une valeur qui doit être fournie au moment de l'exécution mais une fois affectée doit rester la même tout au long du programme, vous devez utiliser lecture seulement. Par exemple, si vous devez affecter l'heure de début du programme ou si vous devez stocker une valeur fournie par l'utilisateur lors de l'initialisation de l'objet et que vous devez la restreindre à d'autres modifications, vous devez l'utiliser en lecture seule.
la source
Ajout d'un aspect de base pour répondre à cette question:
Les propriétés peuvent être exprimées en lecture seule en omettant l'
set
opérateur. Donc, dans la plupart des cas, vous n'aurez pas besoin d'ajouter lereadonly
mot - clé aux propriétés:Contrairement à cela: les champs ont besoin du
readonly
mot - clé pour obtenir un effet similaire:Ainsi, l'un des avantages du marquage d'un champ
readonly
peut être d'obtenir un niveau de protection en écriture similaire à une propriété sansset
opérateur - sans avoir à changer le champ en une propriété, si pour une raison quelconque, cela est souhaité.la source
Soyez prudent avec les tableaux en lecture seule privés. Si ceux-ci sont exposés à un client en tant qu'objet (vous pouvez le faire pour COM Interop comme je l'ai fait), le client peut manipuler les valeurs du tableau. Utilisez la méthode Clone () lors du retour d'un tableau en tant qu'objet.
la source
ReadOnlyCollection<T>
au lieu d'un tableau.ImmutableArray<T>
ce qui évite la boxe vers une interface (IReadOnlyList<T>
) ou le wrapping dans une classe (ReadOnlyCollection
). SesIl peut y avoir un avantage de performance dans WPF, car il supprime le besoin de DependencyProperties coûteuses. Cela peut être particulièrement utile avec les collections
la source
Une autre partie intéressante de l'utilisation du marquage en lecture seule peut être la protection du champ contre l'initialisation dans singleton.
par exemple dans le code de csharpindepth :
joue en lecture seule un petit rôle pour protéger le champ Singleton d'être initialisé deux fois. Un autre détail est que pour le scénario mentionné, vous ne pouvez pas utiliser const car const force la création pendant la compilation, mais singleton effectue la création au moment de l'exécution.
la source
readonly
peut être initialisé lors de la déclaration ou obtenir sa valeur uniquement par le constructeur. Contrairement àconst
cela, il doit être initialisé et déclaré en même temps.readonly
a toutconst
a, plus l'initialisation du constructeurcode https://repl.it/HvRU/1
la source