J'étudie C # et je me demande quel ToString
pourrait être l'intérêt et l'avantage de la substitution , comme le montre l'exemple ci-dessous.
Cela pourrait-il être fait d'une manière plus simple, en utilisant une méthode commune sans le remplacement?
public string GetToStringItemsHeadings
{
get { return string.Format("{0,-20} {1, -20}", "Office Email", "Private Email"); }
}
public override string ToString()
{
string strOut = string.Format("{0,-20} {1, -20}", m_work, m_personal);
return strOut;
}
c#
overriding
3D-kreativ
la source
la source
Console.WriteLine(obj.GetToStringItemsHeadings); Console.WriteLine(obj);
ou similaire.GetToString
le nom de la propriété ... Ensuite, vous obtiendrez par exempleConsole.WriteLine(obj.ItemHeadings)
Réponses:
Avez-vous besoin de passer outre
ToString
? Non.Pouvez-vous obtenir une représentation sous forme de chaîne de votre objet d'une autre manière? Oui.
Mais en utilisant
ToString
vous utilisez une méthode qui est commune à tous les objets et donc d'autres classes connaissent cette méthode. Par exemple, chaque fois que le framework .NET souhaite convertir un objet en une représentation sous forme de chaîne,ToString
est un candidat principal (il y en a d'autres, si vous souhaitez fournir des options de mise en forme plus élaborées).Concrètement,
invoquerait
yourObject.ToString()
.la source
@yourObject
et<%=yourObject%>
va être "ToString-ed".ToString
ne devrait pas réellement changer l'état d'un objet. Mais ce n'est pas ce que je préconisais.ToString
est censé être remplacé. Période. Mettre une mise en garde sur cette déclaration n'est pas productif. Si vous le faites mal - de votre propre faute. En fait, votre élève a enfreint le point 4 de la liste officielle des directives de contournementToString
publiée dans la réponse de David Anderson.Je vais simplement vous donner la réponse directement à partir des directives de conception de cadre de la série de développement .NET.
ÉVITEZ de lancer des exceptions
ToString
CONSIDERER renvoyer une chaîne unique associée à l'instance.
CONSIDERER que la sortie
ToString
est une entrée valide pour toutes les méthodes d'analyse de ce type.DO veiller à ce que
ToString
n'a pas d' effets secondaires observables.FAITES un rapport sur les informations sensibles à la sécurité en remplaçant
ToString
uniquement après avoir demandé une autorisation appropriée. Si la demande d'autorisation échoue, renvoyez une chaîne excluant les informations sensibles à la sécurité.La
Object.ToString
méthode est destinée à être utilisée à des fins d'affichage général et de débogage. L'implémentation par défaut fournit simplement le nom du type d'objet. L'implémentation par défaut n'est pas très utile et il est recommandé de remplacer la méthode.DO override
ToString
chaque fois qu'une intéressante chaîne lisible par l' homme peut être retourné. L'implémentation par défaut n'est pas très utile et une implémentation personnalisée peut presque toujours fournir plus de valeur.DO préfèrent un nom convivial sur un unique , mais pas ID lisible.
Cela vaut également la peine d'être mentionné, comme l'explique Chris Sells dans les directives, qui
ToString
est souvent dangereux pour les interfaces utilisateur. En règle générale, ma règle d'or est d'exposer une propriété qui serait utilisée pour lier des informations à l'interface utilisateur et de laisser leToString
remplacement pour afficher les informations de diagnostic au développeur. Vous pouvez également décorer votre type avecDebuggerDisplayAttribute
.DO essayer de garder la chaîne retournée de
ToString
court. Le débogueur utiliseToString
pour obtenir une représentation textuelle d'un objet à montrer au développeur. Si la chaîne est plus longue que ce que le débogueur peut afficher, l'expérience de débogage est entravée.FAITES la mise en forme de la chaîne en fonction de la culture de thread actuelle lors du renvoi d'informations dépendant de la culture.
DO fournir une surcharge
ToString(string format)
, ou mettre en œuvreIFormattable
, si le retour de la chaîne à partirToString
est sensible à la culture ou il existe différentes façons de formater la chaîne. Par exemple,DateTime
fournit la surcharge et les implémentationsIFormattable
.NE PAS renvoyer une chaîne vide ou null de
ToString
Je jure par ces directives, et vous devriez le faire. Je ne peux pas vous dire comment mon code s'est amélioré uniquement par cette seule directive pour
ToString
. La même chose vaut pour des choses commeIEquatable(Of T)
etIComparable(Of T)
. Ces choses rendent votre code très fonctionnel, et vous ne regretterez pas d'avoir pris le temps supplémentaire pour l'implémenter.Personnellement, je n'ai jamais vraiment
ToString
beaucoup utilisé pour les interfaces utilisateur, j'ai toujours exposé une propriété ou une méthode quelconque. La plupart du temps, vous devez l'utiliserToString
à des fins de débogage et de développement. Utilisez-le pour afficher des informations de diagnostic importantes.la source
Le remplacement
ToString()
vous permet de donner une représentation sous forme de chaîne lisible par l'homme utile d'une classe.Cela signifie que la sortie peut révéler des informations utiles sur votre classe. Par exemple, si vous aviez une classe Person, vous pourriez choisir d'avoir en
ToString()
sortie l'identifiant de la personne, son prénom, son nom de famille, etc. Ceci est extrêmement utile lors du débogage ou de la journalisation.En ce qui concerne votre exemple - il est difficile de dire si votre remplacement est utile sans savoir ce qu'est cette classe - mais l'implémentation elle-même est correcte.
la source
C'est toujours approprié, mais considérez attentivement les intentions derrière ce que vous affichez
Une meilleure question serait de demander:
ToString () est la fenêtre dans l'état d'un objet. Accent sur l' État comme exigence. Les langages OOP tels que Java / C # abusent du modèle OOP en encapsulant tout dans une classe. Imaginez que vous codez dans un langage qui ne suit pas le modèle puissant de la POO; considérez si vous utilisez une classe ou une fonction. Si vous l'utilisez comme une fonction (c'est-à-dire un verbe, une action) et que l'état interne n'est maintenu que temporairement entre les entrées / sorties, ToString () n'ajoutera pas de valeur.
Comme d'autres l'ont mentionné, il est important de considérer ce que vous produisez avec ToString () car il pourrait être utilisé par le débogueur ou d'autres systèmes.
J'aime imaginer la méthode ToString comme le paramètre --help d'un objet. Il doit être court, lisible, évident et facile à afficher. Il doit afficher ce que l'objet n'est pas ce qu'il fait . Avec tout cela à l'esprit, considérons ...
Cas d'utilisation - Analyse d'un paquet TCP:
Pas une capture réseau au niveau de l'application uniquement, mais quelque chose avec plus de viande comme une capture pcap.
Vous souhaitez surcharger ToString () uniquement pour la couche TCP afin de pouvoir imprimer des données sur la console. Que comprendrait-il? Vous pourriez devenir fou et analyser tous les détails TCP (c'est-à-dire que TCP est complexe) ...
Qui comprend:
Mais voudriez-vous recevoir tous ces déchets si vous appeliez TCP.ToString () sur 100 paquets? Bien sûr que non, ce serait une surcharge d'informations. Le choix facile et évident est aussi le plus judicieux ...
Exposez ce que les gens s'attendent à voir:
Je préfère une sortie sensible qui est facile à analyser pour les humains, mais YMMV .
Rien de complexe, la sortie n'est pas pour les machines à analyser (c'est-à-dire à moins que les gens n'abusent de votre code), le but recherché est la lisibilité humaine.
Mais qu'en est-il du reste de ces informations juteuses dont j'ai déjà parlé, n'est-ce pas utile aussi? J'y reviendrai mais d'abord ...
ToString () l'une des méthodes les plus précieuses et sous-utilisées de tous les temps
Pour deux raisons:
Raison 1 - N'abusez pas de l'utilité de ToString ():
Beaucoup de gens utilisent ToString () pour extraire une simple représentation sous forme de chaîne d'un objet. Le manuel C # déclare même:
Affichage, pas de traitement ultérieur. Cela ne veut pas dire, prenez ma belle représentation sous forme de chaîne du paquet TCP ci-dessus et tirez le port source en utilisant un regex :: cringe ::.
La bonne façon de faire les choses est d'appeler ToString () directement sur la propriété SourcePort (qui BTW est un ushort donc ToString () devrait déjà être disponible).
Si vous avez besoin de quelque chose de plus robuste pour empaqueter l'état d'un objet complexe pour l'analyse de la machine, vous ferez mieux d'utiliser une stratégie de sérialisation structurée.
Heureusement, de telles stratégies sont très courantes:
Remarque: sauf si vous utilisez PHP car, herp-derp, il existe une fonction pour cela :: snicker ::
Raison 2 - ToString () ne suffit pas:
Je n'ai pas encore vu de langage qui implémente cela à la base, mais j'ai vu et utilisé des variations de cette approche dans la nature.
Certains d'entre eux incluent:
Fondamentalement, ce désordre poilu de l'état d'un paquet TCP devrait être décrit pour la lisibilité humaine. Pour éviter de `` battre un cheval mort '' en parlant de TCP, je vais `` pointer du doigt '' le cas n ° 1 où je pense que ToString () et ToVerboseString () sont sous-utilisés ...
Cas d'utilisation - Tableaux:
Si vous utilisez principalement une langue, vous êtes probablement à l'aise avec l'approche de cette langue. Pour les gens comme moi qui sautent entre différentes langues, le nombre d'approches variées peut être irritant.
C'est-à-dire que le nombre de fois que cela m'a irrité est supérieur à la somme de tous les doigts de chaque dieu hindou combiné.
Il existe plusieurs cas où les langues communes utilisent hacks et un peu qui obtiennent ce droit . Certains nécessitent une réinvention de la roue, certains font un vidage peu profond, d'autres font un vidage profond, aucun d'entre eux ne fonctionne comme je le voudrais ...
Ce que je demande, c'est une approche très simple:
Où x est le nombre d'articles dans la première dimension et y est le nombre d'articles dans la deuxième dimension ou une valeur qui indique que la deuxième dimension est irrégulière (plage min / max peut-être?).
Et:
Espérons que cela jette un peu de lumière sur un sujet qui me dérange depuis longtemps. À tout le moins, j'ai saupoudré un peu de troll-appât pour que les PHPers votent contre cette réponse.
la source
ToString()
est destiné au débogage, alors pourquoi est-ce le seul moyen d'extraire tout le texte d'un StringBuilder - une fonction importante?C'est une question de bonne pratique autant qu'autre chose, vraiment.
ToString()
est utilisé dans de nombreux endroits pour renvoyer une représentation sous forme de chaîne d'un objet, généralement destinée à être consommée par un humain. Souvent, cette même chaîne peut être utilisée pour réhydrater l'objet (pensez àint
ouDateTime
par exemple), mais ce n'est pas toujours une donnée (un arbre par exemple, peut avoir une représentation sous forme de chaîne utile qui affiche simplement un compte, mais vous ne pouvez clairement pas utiliser que pour le reconstruire).En particulier, le débogueur l'utilisera pour afficher la variable dans les fenêtres de surveillance, les fenêtres immédiates, etc., c'est donc
ToString
réellement inestimable pour le débogage.En général, également, un tel type aura souvent un membre explicite qui renvoie également une chaîne. Par exemple, une paire Lat / Long pourrait avoir
ToDecimalDegrees
quels retours"-10, 50"
par exemple, mais cela pourrait aussi avoirToDegreesMinutesSeconds
, car c'est un autre format pour une paire Lat / Long. Ce même type peut alors également remplacerToString
par l'un de ceux-ci pour fournir une `` valeur par défaut '' pour des choses comme le débogage, ou même potentiellement pour des choses comme le rendu de pages Web (par exemple, la@
construction dans Razor écrit leToString()
résultat d'une expression sans chaîne dans le flux de sortie).la source
object.ToString()
convertit un objet en sa représentation sous forme de chaîne. Si vous souhaitez modifier ce qui est renvoyé lorsqu'un utilisateur appelleToString()
une classe que vous avez créée, vous devez remplacerToString()
cette classe.la source
Bien que je pense que les informations les plus utiles ont déjà été fournies, j'ajouterai mes deux cents:
ToString()
est censé être remplacé. Son implémentation par défaut renvoie le nom du type qui, bien que parfois utile (en particulier lorsque vous travaillez avec beaucoup d'objets), ne suffit pas dans la grande majorité des cas.N'oubliez pas que, à des fins de débogage, vous pouvez compter sur
DebuggerDisplayAttribute
. Vous pouvez en savoir plus ici .En règle générale, sur les POCO, vous pouvez toujours remplacer
ToString()
. Les POCO sont une représentation structurée de données, qui peuvent généralement devenir une chaîne.Concevez ToString pour qu'il soit une représentation textuelle de votre objet. Peut-être ses principaux champs et données, peut-être une description du nombre d'articles dans la collection, etc.
Essayez toujours de placer cette chaîne sur une seule ligne et de ne disposer que des informations essentielles. Si vous avez une
Person
classe avec des propriétés Nom, Adresse, Numéro etc., ne renvoyez que les données principales (Nommez un numéro d'identification).Veillez à ne pas remplacer une bonne implémentation de
ToString()
. Certaines classes de framework implémentent déjàToString()
. Remplacer cette implémentation par défaut est une mauvaise chose: les gens s'attendront à un certain résultatToString()
et en obtiendront un autre.N'ayez pas vraiment peur d'utiliser
ToString()
. La seule chose à laquelle je ferais attention est de renvoyer des informations sensibles. À part cela, le risque est minime. Bien sûr, comme certains l'ont souligné, d'autres classes utiliseront votre ToString chaque fois qu'elles recherchent des informations. Mais diable, quand renvoyer le nom du type sera-t-il considéré comme meilleur que d'obtenir des informations réelles?la source
Si vous ne remplacez pas,
ToString
vous obtenez votre implémentation de classes de base qui, pourObject
est juste le nom de type court de la classe.Si vous voulez une autre implémentation, plus significative ou utile,
ToString
remplacez-la.Cela peut être utile lorsque vous utilisez une liste de votre type comme source de données pour un,
ListBox
car leToString
sera automatiquement affiché.Une autre situation se produit lorsque vous voulez passer votre type à
String.Format
qui invoqueToString
pour obtenir une représentation de votre type.la source
Quelque chose que personne d'autre n'a encore mentionné: en remplaçant
ToString()
, vous pouvez également envisager de l'implémenterIFormattable
afin de pouvoir effectuer les opérations suivantes:Ce qui peut être utile.
la source
IFormattible
interface.System.Object
aura uneToString()
méthode remplaçable , mais vous avez raison de dire que la méthode du formateur ne devrait pas êtreoverride
et devrait vraiment référencer l'IFormattible
interface pour une conformité totale.IFormattable
prend unIFormatProvider
paramètre. Merci de modifier votre message, cependant.Un avantage de la substitution de ToString () est la prise en charge des outils de Resharper: Alt + Ins -> "Formatting members" et il écrit le ToString () pour vous.
la source
Dans certains cas, cela facilite la lecture des valeurs des classes personnalisées dans la fenêtre de surveillance du débogueur. Si je sais exactement ce que je veux voir dans la fenêtre de surveillance, lorsque je remplace ToString avec ces informations, je le vois.
la source
Lors de la définition des structures (effectivement des primitives utilisateur), je trouve que c'est une bonne pratique d'avoir des méthodes de correspondance
ToString
etParse
etTryParse
, en particulier pour la sérialisation XML. Dans ce cas, vous convertirez l'état entier en une chaîne, afin qu'il puisse être lu plus tard.Cependant, les classes sont des structures plus composées qui seront généralement trop complexes pour utiliser
ToString
etParse
. LeursToString
méthodes, au lieu de sauvegarder l'état entier, peuvent être une simple description qui vous aide à identifier leur état, comme un identifiant unique comme un nom ou un identifiant, ou peut-être une quantité pour une liste.De plus, comme l'a dit Robbie, la substitution
ToString
vous permet d'appelerToString
une référence aussi basique que le typeobject
.la source
Vous pouvez l'utiliser lorsque vous avez un objet avec une signification non intuitive de représentation sous forme de chaîne, comme personne. Donc, si vous avez besoin par exemple d'imprimer cette personne, vous pouvez utiliser ce remplacement pour préparer son format.
la source
La
Object.ToString
méthode doit être utilisée à des fins de débogage uniquement. L'implémentation par défaut montre le nom du type d'objet qui n'est pas très utile. Pensez à remplacer cette méthode pour fournir de meilleures informations pour les diagnostics et le débogage. Veuillez noter que les infrastructures de journalisation utilisent souvent également la méthode ToString et que vous trouverez donc ces fragments de texte dans vos fichiers journaux.Ne renvoyez pas de ressources de texte localisées dans la
Object.ToString
méthode. La raison en est que la méthode ToString doit toujours renvoyer quelque chose que le développeur peut comprendre. Le développeur peut ne pas parler toutes les langues prises en charge par l'application.Implémentez l'
IFormattable
interface lorsque vous souhaitez renvoyer un texte localisé convivial. Cette interface définit une surcharge ToString avec les paramètresformat
etformatProvider
. Le formatProvider vous aide à mettre en forme le texte d'une manière tenant compte de la culture.Voir aussi: Object.ToString et IFormattable
la source
Le plus simple dépend de la façon dont votre propriété sera utilisée. Si vous avez juste besoin de formater la chaîne une fois, cela n'a pas beaucoup de sens de la remplacer.
Toutefois, il semble que vous substituez la méthode ToString pour ne pas renvoyer les données de chaîne normales pour votre propriété, mais pour effectuer un modèle de mise en forme standard. Puisque vous utilisez string.format avec padding.
Parce que vous avez dit que vous apprenez, l'exercice semble également aborder les principes fondamentaux de la programmation orientée objet relatifs à l'encapsulation et à la réutilisation du code.
Le string.format prenant les arguments que vous avez définis pour le remplissage garantit que la propriété sera formatée de la même manière à chaque fois pour tout code qui l'appelle. De plus, à l'avenir, vous n'aurez qu'à le changer à un seul endroit au lieu de plusieurs.
Excellente question et aussi quelques bonnes réponses!
la source
Je trouve utile de remplacer la méthode ToString sur les classes d'entités car elle aide à identifier rapidement les problèmes de test, en particulier lorsqu'une assertion échoue, la console de test invoquera la méthode ToString sur l'objet.
Mais en accord avec ce qui a été dit auparavant, il s'agit de donner une représentation lisible par l'homme de l'objet en question.
la source
Je suis satisfait des lignes directrices-cadre mentionnées dans d'autres réponses. Cependant, j'aimerais souligner les objectifs d'affichage et de débogage.
Faites attention à la façon dont vous utilisez
ToString
dans votre code. Votre code ne doit pas s'appuyer sur la représentation sous forme de chaîne d'un objet. Si c'est le cas, vous devez absolument fournir lesParse
méthodes respectives .Comme il
ToString
peut être utilisé partout, cela peut être un problème de maintenabilité si vous souhaitez modifier la représentation sous forme de chaîne d'un objet à un moment ultérieur. Vous ne pouvez pas simplement examiner la hiérarchie des appels dans ce cas pour déterminer si du code va se rompre.la source