34 votes

C#, l'immuabilité et public readonly champs

J'ai lu dans de nombreux endroits que l'exposition des champs publiquement n'est pas une bonne idée, parce que si plus tard vous souhaitez modifier les propriétés, vous devrez recompiler tout le code qui utilise votre classe.

Toutefois, dans le cas de immuable classes, je ne vois pas pourquoi vous ne pourriez jamais besoin de changer de propriétés - vous n'allez pas être en ajoutant de la logique de l'ensemble, après tout.

Des idées sur ce point, ai-je raté quelque chose?

Exemple de la différence, pour ceux qui ont lu le code plus facilement que le texte :)

//Immutable Tuple using public readonly fields
public class Tuple<T1,T2>
{
     public readonly T1 Item1;
     public readonly T2 Item2;
     public Tuple(T1 item1, T2 item2)
     {
         Item1 = item1;
         Item2 = item2;
     }
}

//Immutable Tuple using public properties and private readonly fields
public class Tuple<T1,T2>
{
     private readonly T1 _Item1;
     private readonly T2 _Item2;
     public Tuple(T1 item1, T2 item2)
     {
         _Item1 = item1;
         _Item2 = item2;
     }
     public T1 Item1 { get { return _Item1; } }
     public T2 Item2 { get { return _Item2; } } 
}

Bien sûr, vous pouvez utiliser l'auto-propriétés (public T1 Item1 { get; private set; }), mais cela ne vous arrive "d'accord immutabilité' par opposition à 'garanti immutabilité'...

11voto

Mark Byers Points 318575

C'est une omission évidente à partir des propriétés que vous ne pouvez pas écrire quelque chose comme:

     public T2 Item2 { get; readonly set; } 

Je ne suis même pas sûr readonly c'est le meilleur terme à utiliser pour dire "ne peut être réglé que dans le constructeur", mais c'est ce que nous sommes coincés avec.

C'est en fait une fonctionnalité que beaucoup de gens ont demandé, alors espérons qu'il sera introduit dans une hypothétique nouvelle version de C# dans quelques temps.

Voir cette question.

4voto

LukeH Points 110965

Vous ne pouvez pas besoin d'ajouter de la logique à un poseur dans le futur, mais vous devrez peut-être ajouter de la logique d'un getter.

C'est une bonne raison suffisante pour me permettre d'utiliser les propriétés plutôt que d'exposer les champs.

Si je me sens rigoureux ensuite j'irais pour plein immutabilité (explicite readonly champs de sauvegarde avec exposé des getters et pas de setters). Si je me sens paresseux alors je serais probablement aller pour "convenu immutabilité" (auto-propriétés avec exposé des getters et privé setters).

0voto

IAbstract Points 9384

Selon la pratique habituelle, j'ai suivi votre 2ème exemple en utilisant uniquement 'readonly' lorsque l'objet est public ou vulnérables par inadvertance à la falsification. Je suis en utilisant le " d'accord immutabilité modèle pour un projet en cours, la construction d'un module plug-in. Évidemment, avec un accord sur l'immuabilité, l' readonly protection est enlevée.

Seulement dans de rares circonstances dois-je exposer un terrain public, interne, ou autrement. Il ne fonctionne tout simplement pas à moins que l'écriture d'une propriété {get;} prend plus de temps que je suis disposé à donner.

0voto

Erik Funkenbusch Points 53436

L'idée derrière propriétés, c'est que, même si vous n'avez pas l'intention de chang maintenant ou plus tard, mabye vous devrez peut-être dans certains imprévus façon. Disons que vous avez besoin de changer la lecture pour faire une sorte de calcul, ou l'enregistrement. Peut-être vous avez besoin d'ajouter la gestion des exceptions. Beaucoup de raisons possibles.

Également considérer la sémantique. si T1 est un type de valeur plutôt que d'un type de référence, ensuite l'accès à obj.Item1 renvoie une copie de _Item1 dans la lecture, tout en accédant à Item1 sans un getter ne serait pas récupérer une copie. Cela signifie que, bien que Item1 peut être immuable en interne, la valeur retournée type d'objet n'est pas. Je ne peux pas penser à une raison pourquoi ce serait une bonne chose, mais il ya une différence.

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