6
votes

Quelles sont les bonnes utilisations pour les structures mutables?

Je sais donc que les types de structures / valeurs mutables sont considérés comme «mal» dans .NET. Alors pourquoi est-il possible de les faire? Quels sont quelques bonnes utilisations pour les structures mutables qui justifient l'ajout de la fonctionnalité au CLR dans l'endroit du poing?


2 commentaires

Je suis d'accord, pas une dupe. Ce poste est de savoir pourquoi ils sont diaboliques, vous demandez ce qu'elles sont bonnes.


plus comme anti-questions les uns des autres. Handy de les avoir liés, à travers.


3 Réponses :


2
votes

Les structures partiellement mutables sont bonnes pour faire des constructeurs pour ces structures.

Donc, si vous avez quelque chose comme: xxx

dans un assemblage, puis quelque chose à l'extérieur de cette assemblée Impossible de modifier la structure que vous construisez, mais la construire est facile.


4 commentaires

Vous pouvez affirmer que sur l'API publique qui est une structure immuable, et que Astract pourrait également être écrit avec un constructeur pour définir les champs lisonly (et cela ne changerait pas le API) - mais je vois ce que vous ditesl.


J'allais demander pourquoi pas seulement avoir le paramètre dans le constructeur de structure, je me suis souvenu que vous ne pouvez pas vous débarrasser du constructeur par défaut pour les structures. +1 pour une utilisation légitime.


En fait, ce que je viens de dire n'a aucun sens car il est toujours possible de créer un vide


Ouais, cet exemple de jouet n'est pas le meilleur. Je pensais dans le sens des lignes de Stringbuilder , mais je ne pouvais pas bien venir avec une chose intéressante à construire. Je suis d'accord, j'utilise loadonly et initialise du constructeur pour mes structures. Je n'ai pas utilisé le motif ci-dessus.



3
votes

Une excellente question! Personnellement, je ne suis certainement pas un fan, mais certaines personnes qui manquent de choses comme CF / XNA jureront aveugles qu'elles ont besoin de la performance supplémentaire qu'ils peuvent utiliser de (plus) en utilisant des structures, ce qui les implique généralement d'être mutable. Cet argument a une valeur si la structure est accessible directement dans une matrice, sur un champ public ou accessible via ref , mais dans de nombreux cas, vous pourriez être mordu par le piqué Stack-space en dupliquant une structure sur-taille plusieurs fois sur la pile.

si vous sont en utilisant des structures, mutable ou non, et si vous utilisez la sérialisation , alors une structure immuable complètement peut être un vrai problème. L'immuabilité partielle ou "popsicle" peut être une réponse ici, mais les mêmes cadres qui sont tentant pour les types de valeur ont tendance à avoir plus de restrictions de réflexion, faisant de la sérialisation privée / basée sur le terrain. Tellement mutable est pratique.

Tous ces éléments ci-dessus sont vraiment des exemples d'utilisation d'une structure pour contenir quelque chose qui est réellement mieux classé comme objet. les valeurs pure ne changent pas. Jamais. Si une immuabilité complète va bien.

comme une pensée finale ... Pas une justification de l'existence, mais il fait un excellent entretien fourrage et est idéal pour trébucher les imprudents. Peut-être qu'il a été conçu par des personnes agissant en tant que consultants; p


2 commentaires

Je viens de changer le code que je travaillais pour utiliser des classes mutables où j'avais des structures mutables, a exécuté l'ensemble unique de tests d'unités à une seule fois (l'ensemble multi-fileté a trop peu de cohérence dans les timings pour que cela me dise quoi que ce soit) et a trouvé que la pire gui de la structure est basée sur 10% plus performante que le meilleur de la référence basée sur la référence, pour l'ensemble du jeu (c'est-à-dire, y compris le code qui n'utilise même pas ces objets). Les moyennes sont d'environ 12 à 13% les unes des autres, ce qui concerne ce que Knuth avait dans son optimisation dans son papier célibataire cité :) Pas un type, je l'exposerai, ça vaut ainsi la peine, facile


Bien que oui, cela aide également à ce que les classes exposées qui utilisent ces structures implémentent sont isérialisables afin que la sérialisation ne soit pas à les toucher directement du tout.



2
votes

Les structures mutables sont la seule sorte de type de données dans .NET qui peut implémenter une sémantique de valeur mutable. Certaines personnes comme Eric Lippert les détestent parce qu'elles rendent la vie plus compliquée pour les écrivains du compilateur, mais les sémantiques qu'elles offrent sont souvent beaucoup plus claires que celles disponibles avec des types de référence.

Par exemple, supposons que l'on a une classe et un type de structure, et une interface comme suit: p> xxx pré>

et considérez la méthode suivante: p> xxx pré>

supposant que ce que Munger n'utilise aucun danger Code, lequel des éléments passés peut avoir leur champ .v code> affecté par lequel des quatre déclarations? Je suggérerais que même sans voir toute la définition de Struct1 ou une partie de la mise en œuvre de Munger, on peut dire que Struct1.v ne sera modifié par aucun d'entre eux. Garanti. En outre, Struct2.v peut être modifié par S2, mais pas par l'une des autres déclarations. Encore une fois, garantie. Les valeurs de classe1.v et de classe2.v, cependant, peuvent être modifiées par l'une quelconque des déclarations; La seule façon de savoir laquelle des affirmations pourrait changer CLAS1.V ou CLASS2.V serait d'examiner le code de chaque type qui sera déjà, maintenant ou à l'avenir, implémenter l'exemple. P>

dans d'autres Les mots, les structures offrent une sémantique limitée mais bien définie. Les classes ne le font pas. P>

Incidemment, en raison des limitations de la manière dont les propriétés fonctionnent, on ne peut pas modifier directement, ni passer par référence, champs des propriétés de la structure. Malgré tout, codez comme: P>

List<myStruct> myList;
...
myStruct tempStruct = myList[1];
tempStrict.v = 5;
myList[1] = tempStruct;


3 commentaires

Dans votre dernier paragraphe, première ligne, vous avez inversé le mytructeur et MyClass.


@Joukevandermaas: Mon point dans le dernier paragraphe consistait à dire que si le Code requis pour modifier un champ d'une structure exposé en tant que propriété est plus lourd que idéal, sa sémantique est explicite, contrairement à celles des classes; Le dernier paragraphe parle des problèmes que les classes ont et que les structures ne le font pas. Une structure avec deux champs entiers contient deux entiers. Une classe avec deux terrains entier contient deux entiers, plus une autre chose critique mais non récupérable: l'ensemble de toutes les références. La sémantique d'un type de classe peut être considérablement modifiée par l'existence de ...


... références à cela, mais il n'y a pas de moyen général de savoir si ou lorsque de telles références peuvent exister si un objet instance un autre objet lui-même et n'expose jamais une référence nulle part. Si l'on doit stocker les relations entre les objets, cette interconnexion peut être utile. Si ce que l'on veut, cependant, est simplement de stocker des données, l'interconnexion est juste une complication bourdonnée.