14 votes

Que signifient immuable et readonly en C# ?

Est-il exact qu'il n'est pas possible de modifier la valeur d'un objet immuable ?

J'ai deux scénarios concernant readonly que je veux comprendre :

  1. Que faire si j'ai une collection et que je la marque en tant que readonly comme les suivantes. Puis-je encore appeler _items.Add ?

    private readonly ICollection<MyItem> _items;
  2. Et aussi pour la variable suivante, si plus tard j'appelle _metadata.Change qui changera les valeurs internes d'un couple de variables membres dans le fichier Metadata instance. Est-ce que _metadata encore immuable ?

    private readonly Metadata _metadata;

Pour les deux variables ci-dessus, je comprends parfaitement que je ne peux pas leur attribuer directement de nouvelles valeurs en dehors des initialisateurs et des constructeurs.

24voto

NOtherDev Points 6284

Je vous suggère de lire la série de billets de blog d'Eric Lippert. La première partie est Immutabilité en C# Première partie : les types d'immutabilité . Très instructif et utile, comme toujours. La série décrit ce que signifie pour une variable d'être en lecture seule , immuable etc. en détail.

En général, readonly signifie seulement que vous ne pouvez pas réassigner un champ en dehors du constructeur. Le champ lui-même peut être modifié tant qu'il reste la même instance. Donc oui, vous pouvez ajouter des éléments à la collection stockée dans le champ readonly champ.

En ce qui concerne la mutabilité, c'est plus complexe et cela dépend un peu du type de mutabilité que vous considérez. Lorsque Metadata les valeurs internes sont des références et ces références elles-mêmes (les instances vers lesquelles elles pointent) ne changent pas, vous pourriez dire que Metadata reste non muté. Mais il est muté logiquement . Consultez les articles d'Eric pour en savoir plus.

7voto

Shaun Hamman Points 668

Marquer un champ comme étant en lecture seule signifie que vous ne pouvez pas modifier la valeur de ce champ. Cela n'a aucune incidence sur l'état interne de l'objet qui s'y trouve. Dans vos exemples, bien que vous ne puissiez pas affecter un nouvel objet de métadonnées au champ _metadata, ni une nouvelle ICollection au champ _items (en dehors d'un constructeur), vous pouvez modifier les valeurs internes des objets existants stockés dans ces champs.

5voto

Anders Abel Points 36203

Un site immuable est un objet qui ne peut être modifié, une fois créé. En C#, les chaînes de caractères sont immuables. Si vous examinez les routines de manipulation des chaînes de caractères, vous constaterez qu'elles sont toutes retourne une nouvelle chaîne de caractères, modifiée et laisse la chaîne originale inchangée.

Cela facilite considérablement la manipulation des chaînes de caractères. Lorsque vous avez une référence à une chaîne, vous pouvez être sûr que personne d'autre ne la modifiera inopinément sous vos pieds.

readonly c'est autre chose. Cela signifie que le référence ne peut pas être modifié une fois qu'il a été défini et qu'il ne peut être défini que pendant la construction de l'objet. Dans vos exemples, vous pouvez modifier le contenu de _items ou les propriétés de _metadata mais vous ne pouvez pas attribuer une autre ICollection<MyItem> à la _items ou un autre membre Metadata instance à _metadata .

readonly est réglé sur le référence à un objet. L'immuabilité est une propriété de l'objet lui-même. Elles peuvent être librement combinées. Pour s'assurer qu'une propriété n'est pas modifiée de quelque manière que ce soit, elle doit être une référence en lecture seule à un objet immuable.

4voto

Greg Points 11248

Rien ne vous empêche de modifier un objet stocké dans un fichier de type readonly champ. Vous pouvez donc appeler _items.Add() y metadata._Change() en dehors du constructeur/initialisateur. readonly ne vous empêche que de assignation de de nouvelles valeurs à ces champs après la construction.

3voto

IAbstract Points 9384

private readonly ICollection<MyItem> _items;

N'empêche pas l'ajout d'éléments. Cela empêche simplement _items d'être réaffecté. Il en va de même pour _metadata . Membres accessibles de _metadata peut être modifié - _metadata ne peuvent pas être réaffectés.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X