2009-10-13 2 views
11

Les polices étant immuables perturbent à la fois le programmeur et le GC, car vous devez créer une nouvelle instance à chaque fois.Pourquoi la police est-elle immuable?

Pourquoi Font est-il un type de référence immuable?

+1

Je suis d'accord que quelque chose comme 'Label1.Font = nouvelle police (Label1.Font.Name, Label1.Font.Size + 2.0F, Label1.Font.Style, Label1.Font.Unit);' semble un peu plus de la sommet d'une "juste faire ce que je veux" perspective. – Greg

+0

Permet de rendre les numéros de cartes de crédit immuables afin que n'importe qui peut changer leur numéro à tout moment !!! quel plaisir cela causerait. Et pendant que vous l'ajoutez, rendons le nom de chacun immuable afin que nous puissions les changer toutes les 5 minutes si nous le voulons. –

Répondre

28

Il simplifie l'utilisation du système de rendu. Si la structure permettait à la police d'être modifiable, elle devait détecter les modifications et retravailler régulièrement son rendu. Comme Font crée une ressource native, la garder immuable empêche le système de devoir recréer des handles en interne de façon répétée.

Aussi, je ne suis pas d'accord en termes de "Détresse au programmeur". En rendant la police immuable, cela rend plus évident ce qui se passe lorsque l'utilisateur crée un objet Font. Si vous voulez une nouvelle police, vous devez créer un nouvel objet Font, qui à son tour crée de nouvelles ressources de police natives. Rendre la police immuable rend plus clair ce qui se passe - vous risquez moins de créer accidentellement un problème de performances.

Si la police était modifiable, il serait moins évident que vous ayez créé des poignées à plusieurs reprises lorsque vous avez modifié vos propriétés de police.

+0

Sans mentionner que tout objet (par exemple une fenêtre) qui utilise l'objet de police géré devrait détecter quand la poignée native a changé et associer le nouveau handle à son propre objet natif (par exemple le HWND). –

+1

J'ai toujours pensé que copier et modifier légèrement un objet Police existant était inutilement douloureux. Je n'ai jamais considéré qu'ils créent des ressources natives, donc +1 pour la réponse perspicace. – Greg

+0

trop mauvais bien qu'ils n'aient fait aucune méthode AsBold() qui retourne la nouvelle instance seulement en gras. – Letterman

8

Ils ne sont pas des structures car ils doivent avoir des finaliseurs pour envelopper les objets sous-jacents et fournir une mise en œuvre raisonnable. Qu'est-ce qui se passe si vous Dispose() votre propre copie d'un struct? Est-ce que tu clones le manche à chaque fois?

Il est le stress pas vraiment beaucoup sur le GC ...

Il permet également Font d'être réutilisés en toute sécurité sans vous soucier de ce changement à mi-chemin à travers une opération ;-P

+0

Ce qui aurait été utile aurait été d'avoir une structure FontInfo mutable, et une classe ReadyFont immuable; seul ce dernier aurait besoin de disposer. Des choses comme les propriétés Font sur les contrôles seraient exposées en tant que structure FontInfo, plutôt qu'en tant que ReadyFont. – supercat

4

I En désaccord, cela désole le programmeur. Il y a beaucoup de types immuables dans la BCL qui sont utilisés quotidiennement par les programmeurs et ne causent aucun problème. System.String par exemple.

L'un des avantages d'être immuable est que vous n'avez pas besoin de créer une nouvelle instance à chaque fois. Vous pouvez réutiliser le même type de police aussi souvent que vous le souhaitez car cela ne va pas changer. D'un autre côté, si c'était mutable, vous auriez besoin de faire une copie à chaque fois pour vous assurer que personne d'autre ne l'a changé.

Enfin, Font n'est pas une classe immuable au sens strict du terme. Il implémente IDisposable et, dans la méthode Dispose, supprime l'objet natif sous-jacent.

+0

Cela me rappelle quelque chose que je me suis demandé: qui "possède" des polices, des images et d'autres objets qui sont utilisés dans les contrôles? Si je crée une police et l'affecte à la propriété Font d'un contrôle, copie-t-elle la police transmise de sorte que je devrais Disposer la police une fois que je n'en ai plus besoin ou devrais-je garder une référence à la police ou lui assigner une police différente, ainsi je peux disposer correctement de la police? Mon approche habituelle consiste simplement à abandonner les objets que j'assigne dans un contrôle et à laisser le GC les manipuler, mais cela me semble bizarre. – supercat

+0

@supercat Je n'ai jamais compris la réponse à qui possède 'Font' et je ne crois pas qu'il y ait une bonne réponse. J'ai la même approche d'abandon et laisse le GC les ramasser. – JaredPar

+0

J'oublie si j'ai dit cela avant, mais la propriété Font d'un contrôle semble échantillonner les propriétés de la police sans se soucier de savoir si la police est disposée. On peut Disposer un objet de police et toujours définir une propriété Control.Font à la police disposée. – supercat

13

Eh bien, posez-vous quelques questions.

Tout d'abord, est-ce qu'une police est une chose mutable, comme une liste d'épicerie, ou une chose immuable, comme un nombre? Si vous modélisez une liste d'épicerie dans un programme, il est logique de la rendre modifiable parce que vous pensez généralement à avoir une liste d'épicerie dont le contenu change à mesure que vous manquez ou achetez des articles particuliers. Mais les nombres que vous modélisez typiquement comme étant immuables - le nombre 12 est le nombre 12, maintenant et pour toujours.

Je pense à "Helvetica 12 points gras" comme étant une chose fixe et immuable, comme un nombre, pas quelque chose que je peux changer.

Deuxièmement, est une police plus comme une valeur que vous pouvez faire des copies, ou est-ce plus comme une seule chose que vous pouvez vous référer à?Je ne pense pas à avoir "deux copies" d'Helvetica; Je pense à faire référence à Helvetica. Alors que les numéros que je considère comme ayant des copies différentes pour différents objectifs - quand j'ai 12 articles sur ma liste d'épicerie et 12 clés sur mon trousseau de clés, je ne pense pas à ces deux choses comme "se référant à 12". Puisque je considère les polices comme étant immuables et référencées plutôt que mutables et copiées par valeur, je modéliserais personnellement les polices comme types de référence immuables. Peut-être que vos intuitions sur les polices sont différentes de la mienne.

+0

votre philosophie de traitement des choses me semble irrationnellement incohérent. mais j'ai peut-être manqué quelque chose ... d'abord, vous faites une liste d'épicerie générale à un nombre spécifique. on peut tout aussi bien dire que "melon d'eau, fromage, pain" sera toujours "pastèque, fromage et pain", alors qu'un nombre tel que le prix, peut être très variable ....... un nombre peut nous sembler plus atomique les humains, mais une liste d'épicerie est une entité tout comme un nombre est une entité, ils sont mutables et immuables selon le contexte. tout comme vrai sera toujours vrai, mais une lampe peut être allumée ou éteinte ...... [suite] – Letterman

+0

[part2] est maintenant booléen LOGICALLY immutable? cette question juste sans réponse. les seules choses qui importent sont des considérations pratiques ... Maintenant, "Helvetica 12 points gras" est vraiment chose fixe. juste comme vrai, et le numéro 12. mais la police de mon titre est variable, tout comme le prix d'une voiture ou l'état d'un agneau ...... d'autre part, en fait vous pouvez avoir en C# deux copies de " Helvetica 12 points gras "et vous référencez les nombres dans Java ........ la logique devrait être une considération qui aide à obtenir des résultats esthétiques, mais à la fin, vous devriez être guidé par une considération pratique. – Letterman

+2

@Itay: Lorsque ma femme me demande d'ajouter du lait à la liste d'épicerie, je ne détruis pas l'ancienne liste et produis une nouvelle liste avec du lait ajouté. La liste est modifiable et il est donc logique de modéliser une liste d'épicerie avec un type mutable. Il y a bien sûr des contextes dans lesquels les listes de modélisation sont immuables. –

0

Vous pourriez argumenter qu'il afflige le développeur. Mais vous pouvez également faire le même argument dans le cas contraire.

Par exemple:

// Let me just set the button to the same font as the textbox... 
button.Font = textBox.Font; 

// ...except that I want the button's font to be bold. 
button.Font.Bold = true; 

Le code ci-dessus fixerait un bouton et la police d'une zone de texte en gras en même temps si Font étaient mutable, contrairement aux attentes du promoteur.

0

La police est un objet mal conçu, qui viole le principe de la responsabilité unique, et les difficultés que vous évoquez en découlent. Le problème avec Font est qu'il englobe deux choses: (1) une description de la façon dont une police devrait être dessinée, et (2) un objet de police GDI pour une police avec ces propriétés. Le premier type pourrait être mutable sans conséquence, tandis que rendre ce dernier type mutable poserait toutes sortes de problèmes.

Parmi d'autres choses, considérons la question de savoir comment on devrait suivre la propriété d'une propriété de contrôle typique (par exemple, Button). Si l'on change parfois les polices associées aux contrôles, faut-il créer un objet Police distinct pour chaque contrôle, et le jeter quand on change la police d'un contrôle à autre chose, ou doit-on garder une liste de toutes les polices différentes que l'on utilise pour éviter de créer un nombre excessif d'objets Font identiques, ou quoi?

S'il existait une structure FontDescription (qui était mutable, et non IDisposable) et des choses comme Control.Font étaient de type FontDescription (ou mieux encore, Control exposait une méthode SetFont avec un paramètre de type FontDescription), la question ci-dessus pouvait être répondu assez simplement. Comme il est, l'approche la plus efficace pour définir la police d'un contrôle est de créer un nouvel objet de police (si on n'en a pas déjà un approprié), immédiatement l'éliminer, et ensuite faire l'assignation. La partie "Font description" de la police reste quasi-valide même après la disposition, et c'est tout ce qui est vraiment nécessaire pour la propriété Control.Font.

Questions connexes