Warum / wann wäre es angebracht, ToString zu überschreiben?

103

Ich studiere C # und frage mich, was der Sinn und Nutzen des Überschreibens sein ToStringkönnte, wie im folgenden Beispiel gezeigt.

Könnte dies auf einfachere Weise mit einer gängigen Methode ohne Überschreibung erfolgen?

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;
}
3D-kreativ
quelle
4
Hängt davon ab, ob Sie es tatsächlich verwenden möchten, um das Objekt irgendwo in der Benutzeroberfläche anzuzeigen. Andernfalls dient es normalerweise nur zum Debuggen. Die ToString-Ausgabe wird im Überwachungsfenster von VS angezeigt. (Sie können dies aber auch mit Attributen für die Klasse erreichen.) Wenn Sie Überschriften und Ausgaben haben, sieht es so aus, als würde dieses Programm das Objekt mit Console.WriteLine(obj.GetToStringItemsHeadings); Console.WriteLine(obj);oder ähnlichem ausgeben .
Rup
2
Ich verstehe die Frage nicht wirklich. Kann es anders gemacht werden? Ja. Aber warum willst du das anders machen?
Konrad Rudolph
5
Ich würde wirklich GetToStringden Namen der Immobilie überspringen ... Dann würden Sie zum BeispielConsole.WriteLine(obj.ItemHeadings)
Svish
und ändern Sie die ItemHeadings-Eigenschaft in statisch, da sie kein "dies" benötigt.
eFloh
Vielleicht möchten Sie diese Frage überprüfen: stackoverflow.com/questions/7906828/oo-design-advice-tostring
Yuri Ghensev

Antworten:

127
  • Müssen Sie überschreiben ToString? Nein.

  • Können Sie eine Zeichenfolgendarstellung Ihres Objekts auf andere Weise erhalten? Ja.

Durch die Verwendung verwenden ToStringSie jedoch eine Methode, die allen Objekten gemeinsam ist, und daher kennen andere Klassen diese Methode. Wenn beispielsweise das .NET Framework ein Objekt in eine Zeichenfolgendarstellung konvertieren möchte, ToStringist dies ein Hauptkandidat (es gibt andere, wenn Sie ausführlichere Formatierungsoptionen bereitstellen möchten).

Konkret,

Console.WriteLine(yourObject);

würde anrufen yourObject.ToString().

Konrad Rudolph
quelle
13
Ja. Dies ist auch sehr nützlich in der MVC- oder ASP.Net-Entwicklung, wo @yourObjectund <%=yourObject%>wird "ToString-ed" sein.
Ben Lesh
4
Auch beim Auffüllen einer Combobox ist ToString der Standardaufruf, um den Elementtext abzurufen
Davi Fiamenghi
3
Passen Sie auf solche Praxis auf. Wahre Begebenheit: Ein Schüler hat ToString mit einer Methode überschrieben, die neben der Rückgabe einer Zeichenfolge auch die Daten geändert hat. Er debuggte das Programm, aber während das Programm an einem Haltepunkt stand, änderte sich der Wert ständig. Anscheinend hat sich der Wert jedes Mal, wenn er den Wert von ToString überprüft hat, geändert, obwohl das Programm nicht ausgeführt wurde.
JNF
3
@JNF Was ist "solche Praxis"? ToStringsollte eigentlich nicht den Zustand eines Objekts ändern. Aber das habe ich nicht befürwortet.
Konrad Rudolph
8
@JNF Das akzeptiere ich nicht. ToStringist gemeint sein überschrieben. Zeitraum. Eine Einschränkung dieser Aussage ist nicht produktiv. Wenn Sie es falsch machen - Ihre eigene Schuld. Tatsächlich hat Ihr Schüler gegen Punkt 4 in der offiziellen Liste der Richtlinien zum Überschreiben verstoßen ToString, die in David Andersons Antwort veröffentlicht wurde.
Konrad Rudolph
129

Ich werde Ihnen nur die Antwort direkt aus den Framework Design Guidelines der .NET Development Series geben.

Vermeiden Sie es , Ausnahmen von zu werfenToString

CONSIDER gibt eine eindeutige Zeichenfolge zurück, die der Instanz zugeordnet ist.

Denken Sie daran, dass die Ausgabe von ToStringeine gültige Eingabe für alle Analysemethoden dieses Typs ist.

Stellen Sie sicher, dass ToStringkeine Nebenwirkungen erkennbar sind.

DO Bericht sicherheitsrelevante Informationen durch eine Überschreibung ToStringerst nach einer entsprechenden Berechtigung fordern. Wenn die Berechtigungsanforderung fehlschlägt, geben Sie eine Zeichenfolge ohne sicherheitsrelevante Informationen zurück.

Die Object.ToStringMethode soll für allgemeine Anzeige- und Debugging-Zwecke verwendet werden. Die Standardimplementierung liefert einfach den Objekttypnamen. Die Standardimplementierung ist nicht sehr nützlich, und es wird empfohlen, die Methode zu überschreiben.

DO überschreiben , ToStringwenn eine interessante Menschen lesbaren String zurückgegeben werden kann. Die Standardimplementierung ist nicht sehr nützlich, und eine benutzerdefinierte Implementierung kann fast immer mehr Wert bieten.

Ziehen Sie einen Anzeigenamen einer eindeutigen, aber nicht lesbaren ID vor.

Erwähnenswert ist auch, wie Chris Sells in den Richtlinien erklärt, die ToStringfür Benutzeroberflächen häufig gefährlich sind. Im Allgemeinen gilt als Faustregel, eine Eigenschaft bereitzustellen, die zum Binden von Informationen an die Benutzeroberfläche verwendet wird, und die ToStringÜberschreibung zum Anzeigen von Diagnoseinformationen für den Entwickler zu belassen. Sie können Ihren Typ auch mit dekorieren DebuggerDisplayAttribute.

DO versuchen die Zeichenfolge zurück zu halten ToStringkurz. Der Debugger verwendet ToString, um eine Textdarstellung eines Objekts abzurufen, das dem Entwickler angezeigt werden soll. Wenn die Zeichenfolge länger ist, als der Debugger anzeigen kann, wird das Debuggen behindert.

DO String Formatierung auf der aktuellen Thread Kultur , wenn kulturabhängigen Informationen zurück.

Stellen Sie eine Überladung bereit ToString(string format)oder implementieren Sie sie IFormattable, wenn die Zeichenfolgenrückgabe von kulturabhängig ist oder wenn ToStringes verschiedene Möglichkeiten gibt, die Zeichenfolge zu formatieren. Zum Beispiel DateTimeliefert die Überlastung und Geräte IFormattable.

Geben Sie KEINE leere Zeichenfolge oder Null von zurückToString

Ich schwöre bei diesen Richtlinien, und Sie sollten es tun. Ich kann Ihnen nicht sagen, wie sich mein Code nur durch diese eine Richtlinie für verbessert hat ToString. Das gleiche gilt für Dinge wie IEquatable(Of T)und IComparable(Of T). Diese Dinge machen Ihren Code sehr funktional und Sie werden es nicht bereuen, sich die zusätzliche Zeit genommen zu haben, um irgendetwas davon zu implementieren.

Persönlich habe ich nie wirklich ToString viel für Benutzeroberflächen verwendet, ich habe immer eine Eigenschaft oder Methode irgendeiner Art offengelegt. Die meiste Zeit sollten Sie ToStringfür Debugging- und Entwicklerzwecke verwenden. Verwenden Sie diese Option, um wichtige Diagnoseinformationen anzuzeigen.

David Anderson
quelle
6
Gute Antwort, sind dies die Richtlinien, auf die Sie sich beziehen: msdn.microsoft.com/en-us/library/ms229042.aspx ?
Jodrell
2
@ Jodrell Ich glaube, es ist aus Framework Design Guidelines
Jim Schubert
6
Besseres Zitieren erforderlich.
Ben Voigt
13
Ich wusste nicht, dass SO zu Wikipedia wird.
David Anderson
14
Dies ist nicht der Fall, aber wenn Sie Richtlinien zitieren, ist die Bereitstellung der Quelle ein unbestreitbares Plus.
Falanwe
39

Durch Überschreiben ToString()können Sie eine nützliche, für Menschen lesbare Zeichenfolgendarstellung einer Klasse angeben.

Dies bedeutet, dass die Ausgabe nützliche Informationen zu Ihrer Klasse enthalten kann. Wenn Sie beispielsweise eine Personenklasse ToString()hatten, können Sie festlegen , dass die ID der Person, ihr Vorname, ihr Nachname usw. ausgegeben werden. Dies ist äußerst nützlich beim Debuggen oder Protokollieren.

In Bezug auf Ihr Beispiel ist es schwierig zu sagen, ob Ihre Überschreibung nützlich ist, ohne zu wissen, was diese Klasse ist - aber die Implementierung selbst ist in Ordnung.

Rob Levine
quelle
13

Es ist immer angemessen, aber überlegen Sie genau, welche Absichten hinter dem stehen, was Sie anzeigen

Eine bessere Frage wäre zu fragen:

Warum sollte man ToString () überschreiben?

ToString () ist das Fenster in den Status eines Objekts. Betonung des Staates als Voraussetzung. Stark OOP-Sprachen wie Java / C # missbrauchen das OOP-Modell, indem sie alles in einer Klasse kapseln. Stellen Sie sich vor, Sie codieren in einer Sprache, die nicht dem starken OOP-Modell folgt. Überlegen Sie, ob Sie eine Klasse oder eine Funktion verwenden möchten. Wenn Sie es als Funktion verwenden würden (dh Verb, Aktion) und der interne Status nur vorübergehend zwischen Eingabe / Ausgabe beibehalten wird, bietet ToString () keinen Mehrwert.

Wie bereits erwähnt, ist es wichtig zu berücksichtigen, was Sie mit ToString () ausgeben, da es vom Debugger oder anderen Systemen verwendet werden kann.

Ich stelle mir die ToString-Methode gerne als den Parameter --help eines Objekts vor. Es sollte kurz, lesbar, offensichtlich und leicht anzuzeigen sein. Es sollte anzeigen, was das Objekt ist nicht das, was es tut . In Anbetracht dessen betrachten wir ...

Anwendungsfall - Analysieren eines TCP-Pakets:

Keine Netzwerkerfassung nur auf Anwendungsebene, sondern etwas mit mehr Fleisch wie eine PCC-Erfassung.

Sie möchten ToString () nur für die TCP-Schicht überladen, damit Sie Daten auf der Konsole drucken können. Was würde es beinhalten? Sie könnten verrückt werden und alle TCP-Details analysieren (dh TCP ist komplex) ...

Welches beinhaltet die:

  • Quellport
  • Zielhafen
  • Sequenznummer
  • Bestätigungsnummer
  • Datenoffset
  • Flaggen
  • Fensterversatz
  • Prüfsumme
  • Dringender Zeiger
  • Optionen (Ich werde nicht einmal dorthin gehen)

Aber möchten Sie all diesen Müll empfangen, wenn Sie TCP.ToString () für 100 Pakete aufrufen? Natürlich nicht, es wäre Informationsüberflutung. Die einfache und offensichtliche Wahl ist auch die sinnvollste ...

Zeigen Sie auf, was die Leute erwarten würden:

  • Quellport
  • Zielhafen

Ich bevorzuge eine vernünftige Ausgabe, die für Menschen leicht zu analysieren ist, aber YMMV .

TCP:[destination:000, source:000]

Nichts Komplexes, die Ausgabe ist nicht für Maschinen zum Parsen (dh es sei denn, die Leute missbrauchen Ihren Code), der beabsichtigte Zweck ist die menschliche Lesbarkeit.

Aber was ist mit all dem Rest dieser saftigen Informationen, über die ich vorher gesprochen habe, ist das nicht auch nützlich? Ich werde darauf kommen, aber zuerst ...


ToString () ist eine der wertvollsten und am wenigsten genutzten Methoden aller Zeiten

Aus zwei Gründen:

  1. Die Leute verstehen nicht, wofür ToString () ist
  2. In der Basisklasse 'Object' fehlt eine andere, ebenso wichtige String-Methode.

Grund 1 - Missbrauche nicht die Nützlichkeit von ToString ():

Viele Leute verwenden ToString (), um eine einfache Zeichenfolgendarstellung eines Objekts abzurufen. Das C # -Handbuch besagt sogar:

ToString ist die wichtigste Formatierungsmethode in .NET Framework. Es konvertiert ein Objekt in seine Zeichenfolgendarstellung, sodass es für die Anzeige geeignet ist.

Anzeige, keine Weiterverarbeitung. Das bedeutet nicht, dass ich meine schöne Zeichenfolgendarstellung des obigen TCP-Pakets nehme und den Quellport mit einem regulären Ausdruck :: cringe :: ziehe.

Das Recht Weg, dies zu tun, besteht darin, ToString () direkt in der SourcePort-Eigenschaft aufzurufen (was übrigens ein ushort ist, sodass ToString () bereits verfügbar sein sollte).

Wenn Sie etwas Robusteres benötigen, um den Status eines komplexen Objekts für die Computeranalyse zu verpacken, sollten Sie eine strukturierte Serialisierungsstrategie verwenden.

Glücklicherweise sind solche Strategien sehr verbreitet:

  • ISerialisierbar (C #)
  • Gurke (Python)
  • JSON (Javascript oder eine andere Sprache, die es implementiert)
  • SEIFE
  • etc...

Hinweis: Es sei denn, Sie verwenden PHP, da es für Herp-Derp eine Funktion gibt: snicker ::

Grund 2 - ToString () reicht nicht aus:

Ich habe noch keine Sprache gesehen, die dies im Kern implementiert, aber ich habe Variationen dieses Ansatzes in freier Wildbahn gesehen und verwendet.

Einige davon sind:

  • ToVerboseString ()
  • ToString (ausführlich = wahr)

Im Grunde genommen, dass haarigen Sie einen Staates TCP Packet sollten für die menschliche Lesbarkeit beschrieben. Um zu vermeiden, dass ein totes Pferd über TCP gesprochen wird, zeige ich mit dem Finger auf den ersten Fall, in dem ToString () und ToVerboseString () meiner Meinung nach nicht ausreichend genutzt werden ...

Anwendungsfall - Arrays:

Wenn Sie hauptsächlich eine Sprache verwenden, sind Sie wahrscheinlich mit dem Ansatz dieser Sprache vertraut. Für Leute wie mich, die zwischen verschiedenen Sprachen wechseln, kann die Anzahl der unterschiedlichen Ansätze irritierend sein.

Das heißt, die Häufigkeit, mit der mich dies irritiert hat, ist größer als die Summe aller Finger jedes hinduistischen Gottes zusammen.

Es gibt verschiedene Fälle, in denen Sprachen gängige Hacks verwenden und einige , die es richtig machen . Einige müssen neu erfunden werden, andere machen einen flachen Dump, andere machen einen tiefen Dump, keiner von ihnen funktioniert so, wie ich es gerne hätte ...

Was ich verlange, ist ein sehr einfacher Ansatz:

print(array.ToString());

Ausgaben: 'Array [x]' oder 'Array [x] [y]'

Wobei x die Anzahl der Elemente in der ersten Dimension und y die Anzahl der Elemente in der zweiten Dimension oder ein Wert ist, der angibt, dass die zweite Dimension gezackt ist (Min / Max-Bereich möglicherweise?).

Und:

print(array.ToVerboseString());

Gibt den ganzen She-Bang in hübschem Druck aus, weil ich hübsche Dinge schätze.

Hoffentlich wirft dies ein Licht auf ein Thema, das mich schon lange geärgert hat. Zumindest habe ich den PHPern einen kleinen Trollköder gestreut, um diese Antwort abzulehnen.

Evan Scholle
quelle
Sie haben geschrieben: "Ich habe noch keine Sprache gesehen, die dies im Kern implementiert." Es scheint mir, dass Python dem ziemlich nahe kommt; Wenn Sie beispielsweise ein Array drucken, werden alle Daten präzise dargestellt. Das ist eine Sache, die ich in C # / Java vermisse, obwohl ich ihre Strenge mag. Und wenn Sie ein bisschen über ToString () hinausgehen müssen, wäre es schön, so etwas wie Pythons Listenverständnis-Syntax zu haben. Ich denke string.Join () ist ähnlich, wenn auch weniger flexibel.
Jon Coombs
1
@JCoombs Ich bin nicht anderer Meinung, das Verständnis ist großartig. Das Durchlaufen von Datenstrukturen in Python über das Verständnis erleichtert das Leben erheblich, aber dieser Ansatz erfordert immer noch genaue Kenntnisse der internen Struktur des Objekts. Dies ist bei Klassen, die aus einer externen Bibliothek importiert wurden, nicht immer offensichtlich. Es ist eine gute Praxis für die Autoren der Bibliothek, ToString () zu überschreiben und eine nützliche, für Menschen lesbare Darstellung bereitzustellen. Es wäre jedoch auch gut, eine allgemeine Speicherauszugsmethode zu haben, die die Struktur des Objekts in einem allgemein strukturierten, von Menschen lesbaren Format (ex JSON) ausgibt.
Evan Plaice
Hervorragender Punkt. Anstatt also nur eine Art von Typ anzuzeigen, wird es möglicherweise automatisch zu etwas wie JSON serialisiert. (Bisher habe ich nur .NET-Objekte gesehen, die in XML serialisiert wurden, aber ich bin neu in .NET.) Aber dann besteht die Gefahr möglicherweise in der Versuchung, ToString () als maschinenlesbar zu behandeln? (ZB erwarten, in der Lage zu sein, es zu deserialisieren.)
Jon Coombs
1
@JCoombs Ja, auf funktionaler Ebene dienen JSON und XML demselben Zweck. Viele Leute verwenden ToString als maschinenlesbare Ausgabe. ob das schlecht ist oder nicht, ist umstritten. Mein größtes Rindfleisch ist - oftmals - ein Problem, den Zustand eines Objekts in einem für Menschen lesbaren Format auszugeben. Die Implementierung von ToString () wird häufig nicht ausreichend genutzt, und das Lesen des Status eines Objekts außerhalb der Debugger-Überwachungslisten ist problematisch. Serialisierte Darstellungen eignen sich gut als Backup für die Anzeige des gesamten Status eines Objekts. Bessere Implementierungen von ToString sind jedoch die beste Option.
Evan Plaice
Wenn ToString()es zum Debuggen gedacht ist, warum ist es dann die einzige Möglichkeit, den gesamten Text aus einem StringBuilder zu extrahieren - eine wichtige Funktion?
Dan W
9

Es geht wirklich um gute Praxis.

ToString()wird an vielen Stellen verwendet, um eine Zeichenfolgendarstellung eines Objekts zurückzugeben, im Allgemeinen für den Verbrauch durch einen Menschen. Oft kann dieselbe Zeichenfolge verwendet werden, um das Objekt zu rehydrieren (denken Sie an intoder DateTimezum Beispiel), aber das ist nicht immer gegeben (ein Baum kann beispielsweise eine nützliche Zeichenfolgendarstellung haben, die einfach eine Anzahl anzeigt, die Sie jedoch eindeutig nicht verwenden können das, um es wieder aufzubauen).

Insbesondere wird der Debugger dies verwenden, um die Variable in den Überwachungsfenstern, unmittelbaren Fenstern usw. anzuzeigen, und ist daher ToStringfür das Debuggen von unschätzbarem Wert.

Im Allgemeinen hat ein solcher Typ auch häufig ein explizites Element, das ebenfalls eine Zeichenfolge zurückgibt. Zum Beispiel könnte ein Lat / Long-Paar haben, ToDecimalDegreeswas "-10, 50"zum Beispiel zurückgibt , aber es könnte auch haben ToDegreesMinutesSeconds, da dies ein anderes Format für ein Lat / Long-Paar ist. Derselbe Typ kann dann auch ToStringmit einem dieser Typen überschrieben werden , um einen 'Standard' für Dinge wie das Debuggen oder möglicherweise auch für das Rendern von Webseiten bereitzustellen (z. B. @schreibt das Konstrukt in Razor das ToString()Ergebnis eines Nicht-String-Ausdrucks in das Ausgabestrom).

Andras Zoltan
quelle
6

object.ToString()konvertiert ein Objekt in seine Zeichenfolgendarstellung. Wenn Sie ändern möchten, was zurückgegeben wird, wenn ein Benutzer ToString()eine von Ihnen erstellte Klasse aufruft , müssen Sie ToString()diese Klasse überschreiben .

Robbie
quelle
6

Obwohl ich denke, dass die nützlichsten Informationen bereits bereitgestellt wurden, werde ich meine zwei Cent hinzufügen:

  • ToString()soll überschrieben werden. Die Standardimplementierung gibt den Typnamen zurück, der zwar manchmal nützlich ist (insbesondere bei der Arbeit mit vielen Objekten), aber in den meisten Fällen nicht ausreicht.

  • Denken Sie daran, dass Sie sich beim Debuggen darauf verlassen können DebuggerDisplayAttribute. Sie können mehr darüber lesen Sie hier .

  • In der Regel können Sie bei POCOs immer überschreiben ToString(). POCOs sind eine strukturierte Darstellung von Daten, die normalerweise zu einer Zeichenfolge werden können.

  • Entwerfen Sie ToString als Textdarstellung Ihres Objekts. Vielleicht seine Hauptfelder und Daten, vielleicht eine Beschreibung, wie viele Gegenstände sich in der Sammlung befinden usw.

  • Versuchen Sie immer, diese Zeichenfolge in eine einzelne Zeile einzufügen und haben Sie nur wichtige Informationen. Wenn Sie eine PersonKlasse mit den Eigenschaften Name, Adresse, Nummer usw. haben, geben Sie nur die Hauptdaten zurück (Nennen Sie eine ID-Nummer).

  • Achten Sie darauf, eine gute Implementierung von nicht zu überschreiben ToString(). Einige Framework-Klassen sind bereits implementiert ToString(). Das Überschreiben dieser Standardimplementierung ist eine schlechte Sache: Die Leute erwarten ein bestimmtes Ergebnis ToString()und erhalten ein anderes.

Hab keine Angst vor dem Gebrauch ToString(). Das einzige, worüber ich vorsichtig sein würde, ist die Rückgabe vertraulicher Informationen. Davon abgesehen ist das Risiko minimal. Sicher, wie einige betont haben, werden andere Klassen Ihren ToString verwenden, wenn sie nach Informationen greifen. Aber zum Teufel, wann wird die Rückgabe des Typnamens als besser angesehen, als tatsächliche Informationen zu erhalten?

Bruno Brant
quelle
5

Wenn Sie nicht überschreiben, erhalten ToStringSie Ihre Basisklassenimplementierung, die Objectnur der kurze Typname der Klasse ist.

Wenn Sie eine andere, aussagekräftigere oder nützlichere Implementierung wünschen, ToStringüberschreiben Sie diese.


Dies kann nützlich sein, wenn Sie eine Liste Ihres Typs als Datenquelle für a verwenden, ListBoxda ToStringdiese automatisch angezeigt wird.

Eine weitere situtation tritt auf, wenn Sie Ihre Art weitergeben wollen String.Formatdas Invokes ToStringeine Darstellung Ihrer Art zu erhalten.

Jodrell
quelle
4

Etwas, das noch niemand erwähnt hat: Durch Überschreiben ToString()können Sie auch die Implementierung in Betracht ziehen, um IFormattableFolgendes zu tun:

 public override ToString() {
   return string.Format("{0,-20} {1, -20}", m_work, m_personal);
 }

 public ToString(string formatter) {
   string formattedEmail = this.ToString();
   switch (formatter.ToLower()) {
     case "w":
       formattedEmail = m_Work;
       break;
     case "p":
       formattedEmail = m_Personal;
       break;
     case "hw":
       formattedEmail = string.Format("mailto:{0}", m_Work);
       break;
   }
   return formattedEmail;
}

Welches kann nützlich sein.

Zhaph - Ben Duguid
quelle
Können Sie bitte ein Beispiel für eine Framwork-Klasse geben, die diese Methode zum Überschreiben bereitstellt? Das einzige verwandte Material, das mir im Framework bekannt ist, ist die IFormattibleBenutzeroberfläche.
tm1
@ tm1 Jedes Objekt, von dem erbt System.Object, verfügt über eine überschreibbare ToString()Methode. Sie haben jedoch Recht, dass die Formatierungsmethode nicht vollständig overrideauf die IFormattibleSchnittstelle verweisen sollte , um vollständige Konformität zu gewährleisten .
Zhaph - Ben Duguid
Fast - IFormattablenimmt einen IFormatProviderParameter. Vielen Dank, dass Sie Ihren Beitrag bearbeitet haben.
tm1
In der Tat gibt es zwei Methoden, der Wert, den ich ausdrückte, war in der gezeigten;)
Zhaph - Ben Duguid
3

Ein Vorteil des Überschreibens von ToString () ist die Toolunterstützung von Resharper: Alt + Ins -> "Mitglieder formatieren" und ToString () wird für Sie geschrieben.

Daniel James Bryars
quelle
2

In einigen Fällen ist es einfacher, Werte benutzerdefinierter Klassen im Debugger-Überwachungsfenster zu lesen. Wenn ich genau weiß, was ich im Überwachungsfenster sehen möchte, wenn ich ToString mit diesen Informationen überschreibe, sehe ich es.

Philologon
quelle
1

Wenn ich Strukturen definiere (effektiv Benutzerprimitive), finde ich es eine gute Praxis, Matching ToStringund Parseund zu habenTryParse Methoden, insbesondere für die XML - Serialisierung. In diesem Fall konvertieren Sie den gesamten Status in eine Zeichenfolge, damit er später gelesen werden kann.

Klassen sind jedoch zusammengesetzte Strukturen, die normalerweise zu komplex für die Verwendung von ToStringund sind Parse. ToStringAnstatt den gesamten Status zu speichern, können ihre Methoden eine einfache Beschreibung sein, mit deren Hilfe Sie ihren Status identifizieren können, z. B. eine eindeutige Kennung wie einen Namen oder eine ID oder möglicherweise eine Menge für eine Liste.

Wie Robbie bereits sagte, ToStringkönnen Sie beim Überschreiben ToStringeine Referenz aufrufen, die so einfach wie der Typ ist object.

Dave Cousineau
quelle
1

Sie können dies verwenden, wenn Sie ein Objekt mit einer nicht intuitiven Bedeutung der Zeichenfolgendarstellung haben, z. B. eine Person. Wenn Sie diese Person beispielsweise drucken müssen, können Sie diese Überschreibung zum Vorbereiten des Formats verwenden.

NickF
quelle
1

Die Object.ToStringMethode sollte nur zu Debugging-Zwecken verwendet werden. Die Standardimplementierung zeigt den Objekttypnamen an, was nicht sehr nützlich ist. Überlegen Sie, ob Sie diese Methode überschreiben möchten, um bessere Informationen für Diagnose und Debugging bereitzustellen. Beachten Sie, dass Protokollierungsinfrastrukturen häufig auch die ToString-Methode verwenden. Daher finden Sie diese Textfragmente in Ihren Protokolldateien.

Geben Sie keine lokalisierten Textressourcen innerhalb der Object.ToStringMethode zurück. Der Grund ist, dass die ToString-Methode immer etwas zurückgeben sollte, das der Entwickler verstehen kann. Der Entwickler spricht möglicherweise nicht alle Sprachen, die die Anwendung unterstützt.

Implementieren Sie die IFormattableSchnittstelle, wenn Sie einen benutzerfreundlichen lokalisierten Text zurückgeben möchten. Diese Schnittstelle definiert eine ToString-Überladung mit den Parametern formatund formatProvider. Mit dem formatProvider können Sie den Text kulturbewusst formatieren.

Siehe auch: Object.ToString und IFormattable

jbe
quelle
0

Einfacher hängt davon ab, wie Ihre Immobilie genutzt wird. Wenn Sie die Zeichenfolge nur einmal formatieren müssen, ist es nicht sinnvoll, sie zu überschreiben.

Es scheint jedoch, dass Sie die ToString-Methode überschreiben, um nicht die normalen Zeichenfolgendaten für Ihre Eigenschaft zurückzugeben, sondern ein Standardformatierungsmuster auszuführen. Da Sie string.format mit Auffüllung verwenden.

Da Sie sagten, Sie lernen, scheint die Übung auch auf Kernprinzipien der objektorientierten Programmierung in Bezug auf Kapselung und Wiederverwendung von Code zu stoßen.

Das string.format, das die Argumente verwendet, die Sie für das Auffüllen festgelegt haben, stellt sicher, dass die Eigenschaft jedes Mal für jeden Code, der sie aufruft, auf dieselbe Weise formatiert wird. Außerdem müssen Sie es in Zukunft nur an einer Stelle anstatt an vielen ändern.

Tolle Frage und auch ein paar tolle Antworten!

SoftwareCarpenter
quelle
0

Ich finde es nützlich, die ToString-Methode für Entitätsklassen zu überschreiben, da dies hilft, Probleme beim Testen schnell zu identifizieren, insbesondere wenn eine Zusicherung fehlschlägt. Die Testkonsole ruft die ToString-Methode für das Objekt auf.

Aber in Übereinstimmung mit dem, was zuvor gesagt wurde, ist es eine vom Menschen lesbare Darstellung des fraglichen Objekts.

Ranjez
quelle
0

Ich bin mit den in anderen Antworten genannten Rahmenrichtlinien zufrieden. Ich möchte jedoch die Anzeige- und Debugging-Zwecke hervorheben.

Seien Sie vorsichtig, wie Sie ToStringin Ihrem Code verwenden. Ihr Code sollte nicht auf der Zeichenfolgendarstellung eines Objekts beruhen. Wenn dies der Fall ist, sollten Sie unbedingt die entsprechenden Angaben machenParse Methoden angeben.

Da ToStringes überall verwendet werden kann, kann es ein Problem für die Wartbarkeit sein, wenn Sie die Zeichenfolgendarstellung eines Objekts zu einem späteren Zeitpunkt ändern möchten. In diesem Fall können Sie nicht einfach die Aufrufhierarchie untersuchen, um festzustellen, ob Code beschädigt wird.

tm1
quelle