“const correctness” en C#
Le point de const-correct est d'être en mesure de fournir une vue d'une instance qui ne peuvent pas être modifiés ou supprimés par l'utilisateur. Le compilateur prend en charge ce en pointant du doigt lorsque vous cassez constness de l'intérieur d'une const fonction, ou essayez d'utiliser un non-const fonction de const objet. Donc, sans la copie de la const approche, est-il une méthodologie que je peux utiliser en C# qui a les mêmes objectifs?
Je suis conscient de l'immuabilité, mais qui n'a pas vraiment pour le conteneur d'objets pour n'en citer qu'un exemple.
- Il y a une belle discussion sur les conceptions possibles pour readonly http://blogs.msdn.com/brada/archive/2004/02/04/67859.aspx
- Alors que penser de la mise en œuvre de
const_cast
en C#?
Vous devez vous connecter pour publier un commentaire.
J'ai été confronté à ce problème, un grand nombre de fois trop et finit par l'utilisation d'interfaces.
Je pense qu'il est important d'abandonner l'idée que le C# est une forme, ou même d'une évolution du C++. Ils sont deux langues différentes qui partagent quasiment la même syntaxe.
J'ai l'habitude d'exprimer 'const correctness' en C# par la définition d'une vue en lecture seule d'une classe:
(Customer) myCustomer
. Encore, sans doute la meilleure solution, si vous vous comportez et ne jette pas comme ça 🙂const
, sans le coût supplémentaire de la définition d'une interface séparée et nécessitant l'exécution de l'expédition. Qui est, la langue fournit un moyen simple de mettre en œuvre au moment de la compilation const-interfaces.const
-ness est une partie de la conception et il déclare l'intention tout aussi clairement que l'écriture externe const-interface. Aussi, const-interfaces peut être une tâche complexe s'il doit être traité manuellement, et peut nécessiter l'écriture presque autant d'interfaces que les classes sont présentes dans le composé de type. Qui nous emmène à votre dernière sentece: 'vis les choses à cause de l'oubli d'ajouter la const'. Il est plus facile d'obtenir utilisé pour ajouter de laconst
partout (coût de développement est faible) que de l'écrire en lecture seule interfaces pour chaque classe.ICustomer
pour le nom de la mutable interface? Je crois que cela découle de Microsoft modèle de nommage, par exemple, ICollection<T> et IReadOnlyCollection<T>.IList<T>
ne promet pas que les implémentations seront mutable, ni qu'ils ne sont pas; il perd généralement de covariance pour la capacité de permettre aux clients de se muter implémentations qui se trouvent être mutable sans avoir besoin d'un cast (siIList<T>
prend en charge une forme de rupture de la covariance avec les tableaux: compte tenu des références àIList<Animal>
etAnimal
, la seule façon de dire si l'on peut stocker ces derniers dans un élément de l'ex-est de l'essayer; si par exemple laIList<Animal>
est en fait unCat
et laAnimal
est en fait unDog
, le stockage dans leIList<Animal>
serait un échec.Pour obtenir le bénéfice de la const-folie (ou de la pureté dans la programmation fonctionnelle termes), vous aurez besoin pour concevoir vos cours de façon à ce qu'ils sont immuables, tout comme la Chaîne de classe de c# est.
Cette approche est beaucoup mieux que de simplement le marquage d'un objet en readonly, depuis avec immuables de classes, vous pouvez transmettre les données autour d'facilement dans l'environnement multitâche.
Builder
classes pour les grandes immuable types (Java et .NET définir laStringBuilder
classe qui n'est qu'un exemple).transpose
(avec immuables de la matrice). La classe est trivial, la fonction, et en quelque sorte vous avez le problème-comment venir?matrix
classe et toujours conception de son API, de sorte que la transposition peut être fait efficacement en place lors de l'auto-affectation se fait en C++, le codem = t(m);
peuvent fonctionner en place, même siauto o = t(m);
serait pas fonctionner en place et plutôt de générer une nouvelle instance. Si je devais concevoir une bibliothèque de matrice, c'est comment je pourrais le concevoir.transpose
travaille dans l'usine, ainsi, la (pas de l'appelant) a une autre matrice, conduisant à 8 go d'espace utilisé. Et n'avoir que des objets immuables (et fonctions) à portée de main, l'appelant, n'a même pas de choix à sacrifier la pureté, afin de gagner en performance. Mon point est -- immutabilité n'est pas une solution miracle, ou remplacement pour la mutabilité.m = t(m);
de sorte que aucun de l'espace supplémentaire est nécessaire – ni à l'extérieur det
ou à l'intérieur; il fonctionne place. Bien sûr, alorsm
n'est pas immuable, mais le interface det
, c'est que d'une immuable de la fonction. Et de plus, cela peut être généralisé, afin que les appels commematrix f() { matrix big_mat = /* some code */; return t(big_mat); }
pouvez aussi travail sans exiger de la mémoire supplémentaire, même si le code est entièrement immuable.m
n'est pas immuable" -- bien sûr, mais nous parlions des objets immuables.Je voulais juste vous que beaucoup de Système.Les Collections.Les génériques des conteneurs ont une AsReadOnly méthode qui va vous redonner un immuable collection.
C# n'ont pas cette fonctionnalité. Vous pouvez passer d'argument par valeur ou par référence. Référence elle-même est immuable, sauf si vous spécifiez ref modificateur. Mais fait référence à des données n'est pas immuable. Donc, vous devez être prudent si vous voulez éviter les effets secondaires.
MSDN:
Passage De Paramètres
Interfaces sont la réponse, et sont en fait plus puissant que "const en C++. const est un one-size-fits-all solution pour le problème où "const" est défini comme "ne définit pas les membres ou appeler quelque chose qui définit les membres". C'est un bon raccourci pour const-ness dans de nombreux scénarios, mais pas tous d'entre eux. Par exemple, considérons une fonction qui calcule une valeur en fonction de certains membres, mais aussi met en cache les résultats. En C++, c'est considéré comme un non-const, bien que, dans la perspective de l'utilisateur, il est essentiellement const.
Interfaces de vous donner plus de flexibilité dans la définition du sous-ensemble spécifique de capacités que vous voulez pour fournir à partir de votre classe. Voulez const-ness? Il suffit de fournir une interface avec aucune mutation des méthodes. Souhaitez autoriser la définition de certaines choses, mais pas d'autres? Fournir une interface avec juste ces méthodes.
mutable
.D'accord avec certaines d'autres regardent en lecture seule à l'aide de champs que vous initialiser dans le constructeur, pour créer des objets immuables.
Sinon vous pouvez aussi ajouter d'accès portée sur les propriétés, par exemple la population d'obtenir et protégés définir?
Le problème avec readonly est qu'elle permet uniquement la référence (pointeur) à être constante. La chose référencé (souligné) peut toujours être modifié. C'est la partie la plus délicate, mais il n'y a pas moyen de contourner cela. Pour mettre en œuvre des objets constants en faire pas exposer les mutable méthodes ou des propriétés, mais c'est gênant.
Voir aussi Efficace C#: 50 Moyens Spécifiques pour Améliorer Votre C# (Item 2 - Préférez readonly const.)