Ich studiere C # und frage mich, was der Sinn und Nutzen des Überschreibens sein ToString
kö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;
}
c#
overriding
3D-kreativ
quelle
quelle
Console.WriteLine(obj.GetToStringItemsHeadings); Console.WriteLine(obj);
oder ähnlichem ausgeben .GetToString
den Namen der Immobilie überspringen ... Dann würden Sie zum BeispielConsole.WriteLine(obj.ItemHeadings)
Antworten:
Müssen Sie überschreiben
ToString
? Nein.Können Sie eine Zeichenfolgendarstellung Ihres Objekts auf andere Weise erhalten? Ja.
Durch die Verwendung verwenden
ToString
Sie 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,ToString
ist dies ein Hauptkandidat (es gibt andere, wenn Sie ausführlichere Formatierungsoptionen bereitstellen möchten).Konkret,
würde anrufen
yourObject.ToString()
.quelle
@yourObject
und<%=yourObject%>
wird "ToString-ed" sein.ToString
sollte eigentlich nicht den Zustand eines Objekts ändern. Aber das habe ich nicht befürwortet.ToString
ist 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ßenToString
, die in David Andersons Antwort veröffentlicht wurde.Ich werde Ihnen nur die Antwort direkt aus den Framework Design Guidelines der .NET Development Series geben.
Vermeiden Sie es , Ausnahmen von zu werfen
ToString
CONSIDER gibt eine eindeutige Zeichenfolge zurück, die der Instanz zugeordnet ist.
Denken Sie daran, dass die Ausgabe von
ToString
eine gültige Eingabe für alle Analysemethoden dieses Typs ist.Stellen Sie sicher, dass
ToString
keine Nebenwirkungen erkennbar sind.DO Bericht sicherheitsrelevante Informationen durch eine Überschreibung
ToString
erst nach einer entsprechenden Berechtigung fordern. Wenn die Berechtigungsanforderung fehlschlägt, geben Sie eine Zeichenfolge ohne sicherheitsrelevante Informationen zurück.Die
Object.ToString
Methode 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 ,
ToString
wenn 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
ToString
fü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 dieToString
Überschreibung zum Anzeigen von Diagnoseinformationen für den Entwickler zu belassen. Sie können Ihren Typ auch mit dekorierenDebuggerDisplayAttribute
.DO versuchen die Zeichenfolge zurück zu halten
ToString
kurz. Der Debugger verwendetToString
, 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 sieIFormattable
, wenn die Zeichenfolgenrückgabe von kulturabhängig ist oder wennToString
es verschiedene Möglichkeiten gibt, die Zeichenfolge zu formatieren. Zum BeispielDateTime
liefert die Überlastung und GeräteIFormattable
.Geben Sie KEINE leere Zeichenfolge oder Null von zurück
ToString
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 wieIEquatable(Of T)
undIComparable(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 SieToString
für Debugging- und Entwicklerzwecke verwenden. Verwenden Sie diese Option, um wichtige Diagnoseinformationen anzuzeigen.quelle
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.
quelle
Es ist immer angemessen, aber überlegen Sie genau, welche Absichten hinter dem stehen, was Sie anzeigen
Eine bessere Frage wäre zu fragen:
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:
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:
Ich bevorzuge eine vernünftige Ausgabe, die für Menschen leicht zu analysieren ist, aber YMMV .
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:
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:
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:
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:
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:
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:
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.
quelle
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?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 anint
oderDateTime
zum 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
ToString
fü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,
ToDecimalDegrees
was"-10, 50"
zum Beispiel zurückgibt , aber es könnte auch habenToDegreesMinutesSeconds
, da dies ein anderes Format für ein Lat / Long-Paar ist. Derselbe Typ kann dann auchToString
mit 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 dasToString()
Ergebnis eines Nicht-String-Ausdrucks in das Ausgabestrom).quelle
object.ToString()
konvertiert ein Objekt in seine Zeichenfolgendarstellung. Wenn Sie ändern möchten, was zurückgegeben wird, wenn ein BenutzerToString()
eine von Ihnen erstellte Klasse aufruft , müssen SieToString()
diese Klasse überschreiben .quelle
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
Person
Klasse 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 implementiertToString()
. Das Überschreiben dieser Standardimplementierung ist eine schlechte Sache: Die Leute erwarten ein bestimmtes ErgebnisToString()
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?quelle
Wenn Sie nicht überschreiben, erhalten
ToString
Sie Ihre Basisklassenimplementierung, dieObject
nur 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,
ListBox
daToString
diese automatisch angezeigt wird.Eine weitere situtation tritt auf, wenn Sie Ihre Art weitergeben wollen
String.Format
das InvokesToString
eine Darstellung Ihrer Art zu erhalten.quelle
Etwas, das noch niemand erwähnt hat: Durch Überschreiben
ToString()
können Sie auch die Implementierung in Betracht ziehen, umIFormattable
Folgendes zu tun:Welches kann nützlich sein.
quelle
IFormattible
Benutzeroberfläche.System.Object
, verfügt über eine überschreibbareToString()
Methode. Sie haben jedoch Recht, dass die Formatierungsmethode nicht vollständigoverride
auf dieIFormattible
Schnittstelle verweisen sollte , um vollständige Konformität zu gewährleisten .IFormattable
nimmt einenIFormatProvider
Parameter. Vielen Dank, dass Sie Ihren Beitrag bearbeitet haben.Ein Vorteil des Überschreibens von ToString () ist die Toolunterstützung von Resharper: Alt + Ins -> "Mitglieder formatieren" und ToString () wird für Sie geschrieben.
quelle
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.
quelle
Wenn ich Strukturen definiere (effektiv Benutzerprimitive), finde ich es eine gute Praxis, Matching
ToString
undParse
und 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
ToString
und sindParse
.ToString
Anstatt 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,
ToString
können Sie beim ÜberschreibenToString
eine Referenz aufrufen, die so einfach wie der Typ istobject
.quelle
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.
quelle
Die
Object.ToString
Methode 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.ToString
Methode 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
IFormattable
Schnittstelle, wenn Sie einen benutzerfreundlichen lokalisierten Text zurückgeben möchten. Diese Schnittstelle definiert eine ToString-Überladung mit den Parameternformat
undformatProvider
. Mit dem formatProvider können Sie den Text kulturbewusst formatieren.Siehe auch: Object.ToString und IFormattable
quelle
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!
quelle
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.
quelle
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
ToString
in 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
ToString
es ü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.quelle