Question

Les problèmes sont les suivants:

  • Les bibliothèques graphiques aiment utiliser ToString comme représentation par défaut pour les classes. Là, il doit être localisé.
  • ToString est utilisé pour la journalisation. Là, il devrait fournir des informations relatives à la programmation, n’est pas traduit et inclut des états internes tels que des clés de substitution et des valeurs enum.
  • ToString est utilisé par de nombreuses opérations sur les chaînes qui utilisent des objets comme arguments, par exemple String.Format lors de l'écriture dans des flux. Selon le contexte, vous attendez quelque chose de différent.
  • ToString est trop limité s'il existe plusieurs représentations différentes du même objet, par exemple. une forme longue et une forme courte.

En raison des différents usages, il existe de nombreux types d'implémentation. Ils sont donc trop peu fiables pour être vraiment utiles.

Comment ToString doit-il être implémenté pour être utile? Quand faut-il utiliser ToString , quand doit-il être évité?

La documentation sur .NET Framework indique:

  

Cette méthode retourne une image lisible par l'homme.   chaîne sensible à la culture.

Il existe une question similaire , mais pas la même.

Était-ce utile?

La solution

Il semble que vous attendiez beaucoup d'une petite méthode :) Pour autant que je sache, ce n'est pas une bonne idée d'utiliser une méthode générale dans autant de contextes différents, en particulier lorsque son comportement peut différer d'une classe à l'autre.

Voici mes suggestions:

1.Ne laissez pas les bibliothèques graphiques utiliser ToString () de vos objets. Au lieu d'utiliser des propriétés plus significatives (presque tous les contrôles peuvent être personnalisés pour afficher des propriétés autres que ToString) Par exemple, utilisez DisplayMember. 2.Lorsque vous obtenez des informations sur un objet (pour la journalisation ou d'autres utilisations), laissez à quelqu'un (un autre objet ou l'objet lui-même) ce qui doit être fourni et comment il doit être affiché (un modèle de stratégie peut s'avérer utile)

Autres conseils

Cela dépend de l'utilisation prévue de votre classe. De nombreuses classes n'ont pas de représentation de chaîne naturelle (c'est-à-dire un objet Form). Ensuite, je mettrais en œuvre ToString en tant que méthode informative (texte du formulaire, taille, etc.) utile lors du débogage. Si la classe est censée donner des informations à l'utilisateur, alors je mettrais en œuvre ToString en tant que représentation par défaut de la valeur. Si vous avez par exemple un objet Vector, ToString peut renvoyer le vecteur sous forme de coordonnées X et Y. Ici, je voudrais aussi ajouter des méthodes alternatives s'il y a d'autres façons de décrire la classe. Donc, pour le vecteur, je pourrais ajouter une méthode qui retourne une description sous forme d’angle et de longueur.

À des fins de débogage, vous pouvez également ajouter l'attribut DebuggerDisplay à votre classe. Cela indique comment afficher la classe dans le débogueur, mais cela n’affecte pas la représentation des chaînes.

Vous pouvez également envisager de rendre la valeur renvoyée par ToString analysable afin de pouvoir créer un objet à partir d'une représentation sous forme de chaîne. Comme vous pouvez le faire avec la méthode Int32.Parse.

Une autre solution à prendre en compte est l’intégration étroite entre ToString et le débogueur de Visual Studio. La fenêtre Watch affiche le résultat de ToString en tant que valeur de l'expression. Par conséquent, si votre méthode effectue un chargement différé, a des effets secondaires ou prend un certain temps, un comportement étrange ou un débogueur peut sembler se bloquer. . Certes, ces qualités ne sont pas la marque d’une méthode ToString bien conçue, mais elles se produisent (par exemple, une opération naïve "extraire la traduction de la base de données").

Par conséquent, je considère la méthode ToString par défaut (sans paramètres) comme un point d'ancrage de débogage Visual Studio, ce qui implique qu'elle ne devrait généralement pas être surchargée pour être utilisée par le programme en dehors d'un contexte de débogage.

Alors que ceux qui sont au courant tirent parti des attributs de débogage (DebuggerTypeProxyAttribute, DebuggerDisplayAttribute, DebuggerBrowsableAttribute) pour personnaliser le débogueur, nombreux (notamment moi-même) considèrent généralement la sortie par défaut générée par ToString et affichée dans les fenêtres de surveillance. / p>

Je comprends qu’il s’agit d’une perspective assez stricte - écrire ToString comme un crochet de débogage - mais j’estime que la mise en œuvre d’IFormattable semble être la route la plus fiable et la plus extensible.

Personnellement, je n’implémente pas ToString aussi souvent. Dans de nombreux cas, cela n’aurait pas beaucoup de sens, car le rôle principal d’un type peut être de définir un comportement, pas des données. Dans d'autres cas, cela n'a simplement pas d'importance, car aucun client n'en a jamais besoin.

Dans tous les cas, voici quelques cas où cela a du sens (liste non exhaustive):

  • Si le résultat de ToString est concevable, il sera analysé de nouveau dans une instance du type sans perte de données.
  • Lorsque le type a une valeur simple (c'est-à-dire non complexe).
  • Lorsque le type vise principalement à formater des données en texte.

Je ne pense pas qu'il y ait un conflit entre les scénarios d'utilisation que vous avez répertoriés. Lorsque l'affichage est l'objectif principal, ToString doit fournir un texte convivial, mais pour la journalisation (ou plutôt, comme vous le décrivez, pour le traçage), je dirais que vous ne devriez en aucun cas tracer un élément spécifique à l'interface utilisateur, mais plutôt un objet dont le but est d'écrire des données de trace détaillées.

Donc, il n'y a pas de conflit car il ne devrait pas être du même type selon le principe de responsabilité unique.

N'oubliez pas que vous pouvez toujours surcharger la méthode ToString si vous avez besoin de plus de contrôle.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top