Quels sont les avantages pour le marquage d'un domaine comme `readonly` en C#?
Quels sont les avantages d'avoir un membre de la variable déclarée comme étant en lecture seule? Est-il seulement à les protéger contre quelqu'un changement au cours du cycle de vie de la classe ou il y a un compilateur amélioration de la vitesse grâce à ce mot-clé
- Bonne externes de réponse: dotnetperls.com/readonly
- Intéressant. C'est essentiellement le C# équivalent de ce Java question stackoverflow.com/questions/137868/... la Discussion ici est beaucoup moins chauffé que... hmm...
- Il peut être intéressant de noter que
readonly
champs de types de structure imposer une pénalité sur les performances en comparaison avec les champs mutables qui sont tout simplement pas muté, car l'invocation d'un membre dereadonly
valeur de type champ, le compilateur de faire une copie du champ et d'appeler les états-dessus. - plus sur les performances: codeblog.jonskeet.royaume-uni/2014/07/16/...
Vous devez vous connecter pour publier un commentaire.
La
readonly
mot-clé est utilisé pour déclarer une variable membre d'une constante, mais permet à la valeur calculée au moment de l'exécution. Ceci diffère d'une constante déclarée avec leconst
modificateur, qui doit avoir la valeur est définie au moment de la compilation. À l'aide dereadonly
vous pouvez définir la valeur du champ dans la déclaration, ou dans le constructeur de l'objet que le champ est un membre de.Aussi l'utiliser si vous ne voulez pas avoir à recompiler externe Dll qui font référence à la constante (car il est remplacé au moment de la compilation).
Je ne crois pas qu'il existe des gains de performance de l'aide d'un champ en lecture seule. C'est tout simplement une vérification pour s'assurer qu'une fois que l'objet est entièrement construit, que le champ ne peut pas être pointé vers une nouvelle valeur.
Cependant "readonly" est très différent des autres types de lecture seule sémantique parce qu'il est appliqué au moment de l'exécution par le CLR. Le mot clé readonly compile vers le bas pour .initonly qui est vérifiable par le CLR.
L'avantage réel de ce mot clé est de générer des données immuables structures. Immuable structures de données, par définition, ne peut pas être changé une fois construits. De ce fait, il est très facile de raisonner sur le comportement d'une structure à l'exécution. Par exemple, il n'existe aucun risque de passage d'un immuable d'une structure à l'autre aléatoire portion de code. Ils ne peuvent pas changé, si vous pouvez programmer de manière fiable à l'encontre de cette structure.
Ici est un bon point d'entrée sur l'un des avantages de l'immuabilité: Filetage
Il n'y a pas apparent des avantages de performance à l'aide de
readonly
, au moins aucun que j'ai jamais vu mentionné nulle part. C'est juste pour faire exactement comme vous le suggérez, pour empêcher la modification une fois qu'il a été initialisé.Donc c'est avantageux, car il vous permet d'écrire plus robuste, plus lisible le code. Le réel avantage de ce genre de choses viennent quand vous travaillez dans une équipe ou pour l'entretien. Déclarer que quelque chose comme
readonly
est semblable à l'élaboration du contrat pour que l'utilisation de la variable dans le code. Il pense que l'ajout de la documentation, de la même manière que les autres mots-clés commeinternal
ouprivate
, vous êtes en train de dire "cette variable ne doit pas être modifié après l'initialisation", et d'ailleurs vous êtes l'application de il.Donc, si vous créez une classe et marque quelques variables de membre
readonly
par la conception, alors vous empêcher de vous-même ou un autre membre de l'équipe de faire une erreur, plus tard, lorsqu'ils sont d'une expansion ou la modification de votre classe. À mon avis, c'est un avantage de la valeur (à la petite dépense supplémentaire de complexité du langage comme doofledorfer mentionne dans les commentaires).De le mettre très concrètement:
Si vous utilisez un const dans la dll et dll B références constantes, la valeur de la const seront compilées dans dll B. Si vous redéployez de la dll avec une nouvelle valeur pour que const, dll B sera toujours à l'aide de la valeur d'origine.
Si vous utilisez un readonly dans la dll et dll B références en lecture seule, qui readonly toujours être regardé lors de l'exécution. Cela signifie que si vous redéployez de la dll avec une nouvelle valeur pour que readonly, dll B va utiliser cette nouvelle valeur.
const
peut avoir gain de performance surreadonly
. Voici un peu plus d'explication avec le code : dotnetperls.com/readonlyreadonly
champs. Vous ne pouvez pas stocker unnew object();
dans unconst
et qui a du sens parce que vous ne pouvez pas faire cuire non-valeur des choses telles que des références à d'autres assemblées au cours de la compilation sans changer d'identité.Il y a un cas où le compilateur peut faire une optimisation de la performance basée sur la présence du mot clé readonly.
Cela s'applique uniquement si le champ est en lecture seule aussi marqué comme statique. Dans ce cas, le compilateur JIT peut supposer que ce champ statique ne changera jamais. Le compilateur JIT pouvez prendre cela en compte lors de la compilation de méthodes de la classe.
Exemple typique: votre classe pourrait avoir un static readonly IsDebugLoggingEnabled champ est initialisé dans le constructeur (par exemple, basé sur un fichier de configuration). Une fois les méthodes sont JIT compilé, le compilateur peut omettre des parties entières du code lors de l'enregistrement de débogage n'est pas activé.
Je n'ai pas vérifié si cette optimisation est réellement mis en œuvre dans la version actuelle du compilateur JIT, donc, c'est juste de la spéculation.
Gardez à l'esprit que readonly ne s'applique qu'à la valeur elle-même, donc si vous êtes en utilisant un type de référence en lecture seule ne protège que la référence de changement. L'état de l'instance n'est pas protégé en lecture seule.
N'oubliez pas il y a une solution pour obtenir le
readonly
champs définie en dehors de toute constructeurs à l'aide deout
params.Un peu bordélique mais:
La poursuite de la discussion ici: http://www.adamjamesnaylor.com/2013/01/23/Setting-Readonly-Fields-From-Chained-Constructors.aspx
out
..Si vous avez un pré-définies ou pré valeur calculée doit rester la même à travers le programme, alors vous devriez utiliser constante, mais si vous avez une valeur qui doit être fourni lors de l'exécution, mais une fois affecté doit rester la même tout au long du programme u devrait l'utiliser en lecture seule. par exemple, si vous devez attribuer au début du programme, le temps ou vous devez stocker un utilisateur a fourni une valeur lors de l'initialisation de l'objet et vous devez limiter de plus de changements que vous devez utiliser en lecture seule.
L'ajout d'un aspect fondamental de répondre à cette question:
Propriétés peuvent être exprimées en readonly en laissant la
set
de l'opérateur. Ainsi, dans la plupart des cas, vous n'aurez pas besoin d'ajouter de lareadonly
mot clé de propriétés:Contrairement à ce que: les Champs à la
readonly
mot-clé pour obtenir un effet similaire:Donc, un des avantages de marquage, un domaine que
readonly
peut être de réaliser une écriture similaires niveau de protection de la propriété sansset
opérateur sans avoir à modifier le champ de la propriété, si pour une raison quelconque, c'est souhaitée.Être prudent avec private readonly tableaux. Si celles-ci sont exposées à un client comme un objet (vous pouvez le faire pour COM interop comme je l'ai fait) le client peut manipuler des valeurs de tableau. Utiliser la méthode Clone() lors du retour d'un tableau comme un objet.
ReadOnlyCollection<T>
au lieu d'un tableau.ImmutableArray<T>
, ce qui évite de boxe à une interface (IReadOnlyList<T>
) ou en l'enveloppant dans une classe (ReadOnlyCollection
). Il a des performances comparables à celles des natifs des tableaux: blogs.msdn.microsoft.com/dotnet/2013/06/24/...readonly
peut être initialisée lors de la déclaration ou de la valeur de l'constructeur uniquement. Contrairement àconst
il doit être initialisé et déclarer en même temps.readonly
a toutconst
a plus de constructeur d'initialisationcode https://repl.it/HvRU/1
Étonnamment, readonly peut effectivement se traduire par un ralentissement de code, comme Jon Skeet constaté lors de l'essai de son Noda de la bibliothèque. Dans ce cas, un test qui a couru dans les 20 secondes a pris seulement 4 secondes après le retrait de readonly.
https://codeblog.jonskeet.uk/2014/07/16/micro-optimization-the-surprising-inefficiency-of-readonly-fields/
readonly struct
en C# 7.2, l'avantage de rendre le domaine de la non-lecture seule s'en va.Il peut y avoir un avantage de performance dans WPF, car elle élimine le besoin de coûteux DependencyProperties. Cela peut être particulièrement utile avec des collections
Une autre partie intéressante de l'utilisation de readonly le marquage peut être la protection de champ à partir de l'initialisation en singleton.
par exemple dans le code de csharpindepth:
readonly joue un petit rôle de protection de champ Singleton d'être initialisés à deux reprises. Un autre détail, c'est que pour le scénario mentionné, vous ne pouvez pas utiliser const car const forces de création lors de la compilation, mais singleton fait de la création au moment de l'exécution.