30 votes

Où sont les fichiers en lecture seule / const dans .NET?

En C++, vous verrez void func(const T& t) partout. Cependant, je n'ai pas vu quelque chose de semblable dans .NET. Pourquoi?

J'ai remarqué une belle quantité de paramètres à l'aide struct. Mais je ne vois pas de fonctions avec readonly/const. En fait, maintenant que je l'ai essayé, je ne pourrais pas utiliser ces mots-clés pour faire une fonction qui s'engage à ne pas modifier une liste qui est passée. Il n'y a pas moyen de la promesse de l'appelant que cette fonction ne sera jamais modifier le contenu de la liste? Il n'y a pas moyen de dire à appeler du code et de dire cette liste ne doit jamais être modifié? (Je sais que je peux le clone de la liste ou de regarder la documentation mais j'aime bien les erreurs de compilation parfois)

44voto

LBushkin Points 60611

L'immuabilité est encore un domaine où C# est à maturité. Jusqu'à présent, C# n'a pas adopté l' const de la sémantique de C++ ... ce qui je pense est une bonne chose. Le comportement de l' const en C++ souvent fait qu'il est difficile de concevoir les hiérarchies de classe qui a travaillé de la façon que vous le vouliez. Il n'était pas rare de voir le code parsemé d' const_cast<> de contourner constness où il n'était pas souhaitable. Heureusement, les concepteurs de C# inventer une simple mais toujours expressif alternative.

À l'heure actuelle, il n'existe pas de fonctionnalité de langage qui marque les paramètres ou les objets passés à des méthodes comme immuable. Le meilleur que vous pouvez faire est de passer d'un objet à l'aide d'une interface (ou mieux encore un wrapper) qui ne permet les opérations de lecture.

Pour certains de la norme collection .NET, vous pouvez utiliser l' ReadOnlyCollection wrapper, qui englobait tout mutable ICollection type au sein d'une lecture seule contenant.

La création d'immuable types exige de la planification et de prise de conscience des fonctionnalités de langage. Par exemple, l' readonly mot-clé est votre ami. Il vous permet de déclarer des membres d'une classe ou structure comme immuable. Malheureusement, cette immutabilité ne s'applique qu'à la référence, et non les membres de l'objet référencé. Ce que cela signifie est que vous pouvez déclarer:

private readonly int[] m_Values = new int[100];

public void SomeMethod()
{
    m_Values = new int[50]; // illegal, won't compile!
    m_Values[10] = 42;      // perfectly legal, yet undesirable
}

Dans l'exemple ci-dessus, la référence à la matrice est immuable, mais les différents éléments du tableau ne sont pas. Ce problème s'étend au-delà des tableaux, bien sûr.

Une pratique que j'ai trouvé utile lors de la conception immuable types, est de séparer l'immuable comportement dans sa propre interface qui est ensuite mis en œuvre par une classe qui gère les données. L'interface n'expose les propriétés et méthodes qui sont garantis de ne pas la mutation de l'état de l'objet. Il est alors possible de passer les instances de votre type de méthodes que les paramètres de ce type d'interface. C'est une forme faible de l'immuabilité de soutien - depuis la méthode appelée peut souvent mettre la référence à la mutable type. Un mieux, mais de plus en plus lourde alternative, est de créer un wrapper de mise en œuvre qui met en œuvre la même interface et maintient une référence vers l'instance réelle (un peu comme l' ReadOnlyCollection t). C'est plus de travail, mais offre une plus forte garantie pour l'immutabilité.

L'approche que vous choisissez dépend de la façon dont des garanties importantes de l'immuabilité et de la façon dont beaucoup de temps et d'effort que vous êtes prêt à dépenser pour y arriver.

Si vous êtes intéressés à en savoir plus sur ce sujet, Eric Lippert a une excellente série d'articles sur l'immuabilité en C#.

7voto

Mark Byers Points 318575

Il n'y a pas de modificateur const pour les paramètres de méthode en C #. Si vous voulez avoir quelque chose de similaire à const, vous pouvez utiliser des types immuables dans vos interfaces. Par exemple, une méthode peut accepter un IEnumerable<T> au lieu d'un type de collection mutable. Vous pouvez également consulter ReadOnlyCollection .

5voto

Joel Coehoorn Points 190579

J'ai remarqué une belle quantité de paramètres à l'aide struct.

Une chose à noter ici est que C# exagère la différence entre la structure et de la classe par rapport à C++, en exagérant la différence entre les types valeur et les types référence. En C#, toutes les classes sont des types référence, et toutes les structures sont des types de valeur. Dans .Net, tout est passé par valeur par défaut.

Le résultat de cette distinction pour les types de valeur, c'est que tous les types de valeur sont copiés lorsqu'ils sont passés à une fonction. Si vous passez une structure à une fonction, vous avez la garantie que la fonction ne modifie pas l'original struct parce que la fonction ne fonctionne qu'en un exemplaire. L'ajout de const d'un tel paramètre est stupide.

Les types de référence sont passés par valeur, aussi. Ou, plus précisément, la référence elle-même est passé par valeur. Si vous avez une copie de la référence, mais c'points (renvoie) le même objet. Ainsi, les modifications apportées à l'objet par la fonction persisteront après la fonction se termine.

Sur la surface, l'ajout d'un const option, au moins pour les types référence, semble être une bonne idée. Là où ça devient un peu glauque est avec des effets secondaires. Ou, plutôt, comment est-il appliqué? Bien évidemment, il est assez facile de dire que votre code ne pouvez pas utiliser les accesseurs de propriété. Mais quelles sont les autres méthodes? Tout appel de méthode pourriez avoir besoin de changer l'objet. Même propriété getters pourriez avoir un effet secondaire qui change quelque chose (dire vous mettre en œuvre une fonctionnalité de sécurité de noter quand quelque chose a été dernier accès). Allez-vous refuser de lire l'accès à une propriété en raison de l'effet secondaire?

1voto

Hans Passant Points 475940

Le problème est que const, l'exactitude utilisé en C/C++ n'est appliquée que par le compilateur. Et facilement contourné btw. Le CLR effectivement applique de sécurité de type dans le code managé, pas le compilateur. Nécessairement donc, à cause de la .NET framework prend en charge de nombreuses langues. Le type de système et des règles d'interaction sont énoncées dans la CLI, une langue commune de l'infrastructure qui doit servir de nombreux objectifs et les maîtres.

Const correctness est rare dans les langues actuelles. Personnellement, je ne connais que le C++, un langage qui n'est pas porté à la CLI. L'application de règles sur les langues, qui n'ont nulle part près de la syntaxe pour eux, c'est difficile. Quelque chose d'aussi simple que unsigned les types intégraux ne sont pas dans les CLS de gauche, un notable de la marque sur la conception de la base assemblées.

L'immutabilité (la vraie, pas truquée avec un compilateur) garde le MSFT équipes de la pensée. Il est populaire, je sais que l'équipe C#, a été de penser à elle. Bon pour la concurrence, et cætera. Eric Lippert a fait un 11 de la partie blog de la série sur elle, un peu s'est éteinte bien. Trop gros pour un mec et de son public. Si il y a un réel mouvement d'arriver en œuvre, j'ai confiance en eux, d'y réfléchir et de le faire fonctionner. Un de ces jours. Certaines langues.

0voto

MUG4N Points 5011

car je sais que ce n'est pas possible de manière simple. Peut-être que cet article vous donne quelques idées:

http://www.c-sharpcorner.com/UploadFile/bulentozkir/PassingConstInCS11082005014622AM/PassingConstInCS.aspx

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