Double Possible:
Pourquoi sont mutables les structures du mal?Je l'ai lu dans beaucoup d'endroits, y compris ici que c'est mieux de faire des structs comme immuable.
Quelle est la raison derrière tout cela? Je vois beaucoup de Microsoft-créé des structures qui sont mutables, comme ceux de xna. Il y a probablement beaucoup plus dans la BCL.
Quels sont les avantages et les inconvénients de ne pas suivre cette directive?
Réponses
Trop de publicités?Les structures doivent représenter des valeurs . Les valeurs ne changent pas. Le nombre 12 est éternel.
Cependant, considérez:
Foo foo = new Foo(); // a mutable struct
foo.Bar = 27;
Foo foo2 = foo;
foo2.Bar = 55;
Maintenant, foo.Bar et foo2.Bar sont différents, ce qui est souvent inattendu. Surtout dans les scénarios comme les propriétés (heureusement, le compilateur le détecte). Mais aussi des collections etc; comment les avez-vous jamais mutés sensiblement?
La perte de données est beaucoup trop facile avec des structures mutables.
Le gros con c'est que les choses ne se comportent pas de la façon dont vous vous attendez à - particulièrement si la mutabilité provient d'un mélange de la valeur directe et d'un type de référence à l'intérieur.
Pour être honnête, je ne me souviens pas du haut de ma tête tous les problèmes bizarres j'ai vu des gens dans les groupes de discussion quand ils ont utilisé les structures mutables - mais ces raisons existent certainement. Mutable structs causer des problèmes. Rester à l'écart.
EDIT: je viens de trouver un e-mail que j'ai écrit il y a longtemps sur ce sujet. Il élabore un tout petit peu:
C'est philosophiquement faux: une struct devrait représenter une sorte de valeur fondamentale. Ces derniers sont en fait immuable. Vous n'obtenez pas de changer le numéro 5. Vous pouvez modifier la valeur d'une variable de 5 à 6, mais vous n'avez pas logiquement faire un changement de la valeur elle-même.
C'est pratiquement un problème: il crée beaucoup de situations étranges. C'est particulièrement mauvais si c'est modifiable via une interface. Ensuite, vous pouvez commencer à changer la boîte valeurs. Ick. J'ai vu beaucoup de messages du forum qui sont dus à des gens qui essaient d'utiliser les structures mutables et en cours d'exécution dans des questions. J'ai vu un très étrange LINQ exemple qui n'était pas parce qu'
List<T>.Enumerator
est un struct, par exemple.
J'utilise les structures mutables souvent dans ma (critique pour les performances) de projet - et je n'ai pas de problèmes parce que je comprends les implications de la sémantique de copie. Aussi loin que je peux dire, la principale raison pour laquelle les gens défenseur immuable des structures est donc que les gens qui ne pas comprendre les implications ne peuvent pas faire eux-mêmes en difficulté.
Ce n'est pas une chose terrible - mais nous sommes en danger maintenant de devenir "la vérité de l'évangile", alors qu'en fait, il y a des moments où il est véritablement la meilleure option pour faire une struct mutable. Comme avec toutes les choses, il y a des exceptions à la règle.
Il n'y a rien de moins cher à manipuler qu'une structure mutable, c'est pourquoi vous la voyez souvent dans du code haute performance comme les routines de traitement graphique.
Malheureusement, les structures mutables ne fonctionnent pas bien avec les objets et les propriétés, il est beaucoup trop facile de modifier une copie d'une structure au lieu de la structure elle-même. Ainsi, ils ne conviennent pas à la plupart de votre code.
PS Pour éviter le coût de la copie de structures mutables, elles sont généralement stockées et transmises dans des tableaux.
La raison technique est que mutable structures semblent être en mesure de faire des choses qu'ils ne font en réalité. Depuis le moment de la conception de la sémantique sont les mêmes que les types référence, cela devient source de confusion pour les développeurs. Ce code:
public void DoSomething(MySomething something)
{
something.Property = 10;
}
Se comporte tout à fait différemment selon si MySomething
est struct
ou class
. Pour moi, c'est une impérieuse, mais pas la raison la plus convaincante. Si vous regardez DDDs' Objet de Valeur, vous pouvez voir la connexion à la façon dont les structures doivent être traités. Un objet de valeur dans DDD peut être mieux représenté comme un type de valeur dans .Net (et donc une structure (struct). Parce qu'il n'a pas d'identité, il ne peut pas changer.
Penser en termes de quelque chose, comme votre adresse. Vous pouvez "modifier", votre adresse, mais l'adresse n'a pas changé. En fait, vous avez une nouvelle adresse qui vous sont attribués. Sur le plan conceptuel, cela fonctionne, parce que si vous avez réellement changé votre adresse, vos colocataires aurait à se déplacer trop.