Overriding ToString () für Debugging und Logs - sollte die Zeichenfolge lokalisiert werden?

8

Ich entwerfe eine .NET-Bibliothek, die von anderen Entwicklern verwendet wird, die sowohl Web- als auch Desktop-Anwendungen erstellen. Ich überschreibe ToString() in verschiedenen Klassen, um Informationen zum Debuggen und zur Aufnahme in Anwendungsprotokolldateien bereitzustellen.

Einige meiner Klassen enthalten Zahlen und Daten.

Betrachte ein Objekt, das ein DateTime namens date und ein double genannt value (und vielleicht auch andere Felder) enthält ... Wenn ich das ToString() des Objekts überschreibe, möchte ich das tun etwas wie:

%Vor%

Aber das wird das Ergebnis von date.ToString() und value.ToString() beinhalten, was mir Strings geben wird, die nach Thread.CurrentThread.CurrentCulture lokalisiert sind.

Und das scheint mir falsch zu sein. Die von meinen ToString() -Implementierungen zurückgegebenen Zeichenfolgen dienen zum Debuggen und Protokollieren von Nachrichten, nicht für Benutzeroberflächen. Ich denke also, lokalisierte Strings zurückzugeben, könnte die Dinge nur verwirren. Wenn "2.341" in den Protokolldateien angezeigt wird, müsste ein Entwickler den Wert des CurrentCulture des Threads kennen, um zu wissen, ob es zweitausend 341 oder 2 Punkt 341 bedeutet. Es ist noch verwirrender mit Daten - eine Zeichenfolge wie xx / xx / xxxx könnte TT / MM / JJJJ oder MM / TT / JJJJ sein. Ich möchte nicht, dass meine ToString() -Methoden diese Art von Ambiguität erzeugen.

Meine Neigung besteht also darin, meine ToString() -Methoden kulturunabhängig zu machen, um sicherzustellen, dass alle zurückgegebenen Strings über Kulturen hinweg konsistent sind. Zum Beispiel würden meine ToString() -Methoden intern value.ToString(CultureInfo.InvariantCulture) verwenden, um eine Zahl zu formatieren.

Die Norm in .NET-Bibliotheken scheint jedoch darin zu bestehen, CurrentCulture in den Standard-No-Args ToString() -Implementierungen zu verwenden. Viele Objekte, die eine ToString() -Methode haben, haben auch eine ToString(IFormatProvider) -Methode. Es ist, als hätten die Designer von .NET entschieden, dass die Standardverwendung von ToString() für die Anzeige der Benutzeroberfläche (lokalisiert) und das Debugging und die Protokolle (für die Sie ToString(CultureInfo.InvariantCulture) aufrufen müssten) sekundär sind / p>

Wenn ich also meine ToString() -Methoden auf eine kulturunempfindliche Art und Weise implementiere, denke ich, dass ich etwas gegen den Strich gehen würde. Aber es scheint albern, kultursensitive Zeichenfolgen standardmäßig zu erstellen, wenn Kultursensitivität für Protokolldateien oder Debugging keinen Sinn ergibt.

Ich könnte die CurrentCulture verwenden, um Zahlen und Datumsangaben in meinen standardmäßigen ToString() Implementierungen darzustellen, und auch ToString(FormatProvider) Methoden, damit Leute eine kulturunempfindliche Zeichenfolge für die Verwendung in Logfiles usw. erhalten können. Aber das scheint dumm, da es Entwickler nur dazu zwingt, mehr Code zu schreiben, um die kulturunempfindliche Zeichenfolge zu erhalten, von der ich vermute, dass sie sie wollen (ob sie es in Betracht gezogen hat oder nicht).

Die Quintessenz ist, dass eine Zeichenkette wie ObjectName[value=12.234, date=2011-10-01] niemals in einer Benutzerschnittstelle erscheinen sollte. Warum also sollte ein Programmierer jemals wollen, dass er lokalisiert wird?

Ich habe den Ratschlag in den Framework Design Guidelines zur Implementierung von ToString() gelesen. Einige der Ratschläge scheinen etwas widersprüchlich zu sein. Zum Beispiel:

  

Ich halte ToString für eine besonders gefährliche Methode, um UI-generische Typen bereitzustellen, da es wahrscheinlich mit einer bestimmten Benutzeroberfläche implementiert wird, was es für andere UI-Anforderungen nutzlos macht. Um mich nicht auf diese Weise zu verführen, bevorzuge ich es, meine ToString -Ausgabe so geeky wie möglich zu machen, um zu betonen, dass die einzigen "Menschen", die jemals die Ausgabe sehen sollten, "Entwicklermenschen" sind (eine Unterart für sich). p>

und

  

Der wichtigste Wert von ToString ist, dass der Debugger ihn als Standardmethode zum Anzeigen des Objekts verwendet.

scheint nicht wirklich zu passen:

  

DO Formatierung von Strings basierend auf der aktuellen Thread-Kultur beim Zurückgeben von kulturabhängigen Informationen.

und

  

Verwenden Sie die CultureInfo -Instanz, die von der Eigenschaft CurrentCulture eines Threads zurückgegeben wird, um ein beliebiges numerisches Datum oder ein Datum

zu formatieren

Ich bin dafür, den Richtlinien zu folgen und APIs zu schreiben, die genau das tun, was Programmierer erwarten. Aber wenn ToString() für Programmierer ist, dann scheint es albern, es zu lokalisieren. Der C # -Compiler wird es einem Programmierer nicht erlauben, ein doppeltes Literal mit einem systemabhängigen Dezimaltrennzeichen zu schreiben, also sollten sich ToString() für Programmierer geschriebene Methoden ähnlich verhalten?

Was denkst du? Wenn die Ausgabe von ToString() nicht für die Verwendung in einer Benutzerschnittstelle bestimmt ist, sollten die darin enthaltenen Zahlen und Daten lokalisiert sein oder nicht?

Aktualisieren

Ich habe einige Tests mit dem DebuggerDisplay -Attribut durchgeführt, und es sieht so aus, als ob es standardmäßig Zahlen auf eine kulturunempfindliche Weise formatiert.

%Vor%

Führen Sie diesen Test im Debugger aus, und wenn er bricht, können Sie sehen, dass das in double enthaltene DoubleHolder mit einem . als Dezimaltrennzeichen formatiert ist.

Schließen Sie dann Visual Studio, ändern Sie die regionalen Optionen für Standards und Formate für Windows auf Französisch, und führen Sie den Test erneut aus.Sie werden sehen, dass doubleString ein , als Dezimaltrennzeichen hat, aber der Debugger zeigt immer noch double in DoubleHolder mit .

an

Ich hätte das gerne an einer richtigen französischen Version von Windows mit Visual Studio auf Französisch getestet. Wenn Sie in Visual Studio zu Extras - & gt; Optionen - & gt; Umwelt - & gt; Internationale Einstellungen können Sie die Sprache auf "Wie Microsoft Windows" einstellen. In meiner Installation war standardmäßig "Englisch" eingestellt. Aber um Visual Studio auf Französisch zu bekommen, brauchen Sie Windows auf Französisch, und meine Version von Windows scheint nur Englisch zu sein. Wenn jemand ein französisches Windows oder ein anderes Gebietsschema hat, das , als Dezimaltrennzeichen verwendet, wäre es großartig, wenn Sie einfach überprüfen könnten, ob der Debugger . oder , als Dezimaltrennzeichen in formatierten Doppeln verwendet.

Ich frage mich, ob Thread.CurrentThread.CurrentUICulture einen Unterschied machen könnte, wie der Debugger von Visual Studio Dinge zeigt, und ich bin mir nicht sicher, ob ich die Einstellungen so einstellen würde, wie Visual Studio vollständig auf Französisch läuft / p>

Aber von oben sieht es so aus, als ob der Debugger konsistent . als Dezimaltrennzeichen verwendet. Dies bedeutet für mich, dass eine kulturunabhängige ToString () - Methode in Ordnung ist, wahrscheinlich vorzuziehen, wenn sie für Debugging-Zwecke gedacht ist.

    
MB. 05.11.2011, 15:12
quelle

2 Antworten

15

Beim Debuggen sollten Sie sich Debugger-Anzeigeattribute ansehen, nicht ToString() .

%Vor%

Was die Lokalisierung von ToString() betrifft, werde ich die Möglichkeit eines Kommentars weitergeben.

    
ANeves 05.11.2011 15:23
quelle
7

IMO die zwei einzigen wichtigen Dinge hier sind:

  • dass Sie über die beabsichtigte Verwendung nachgedacht haben und Kultur entsprechend anwenden
  • dass das Verhalten eindeutig dokumentiert ist

Wenn dies die Protokollierung ist, scheint invariant zu sein. Wenn die beabsichtigte Verwendung IDE-Anzeige war, würde ich es auf den aktuellen Thread lokalisiert lassen.

Wenn Sie sich nicht sicher sind, ziehen Sie in Erwägung, eine ToString (CultureInfo) -Methode hinzuzufügen, und der Aufrufer kann dann tun, was er möchte. In diesem Szenario würde ich annehmen, dass der Standardwert current-culture ist und dass der Logging-Code explizit Invariante anfordern sollte (vielleicht auch über IFormattable).

    
Marc Gravell 05.11.2011 15:18
quelle

Tags und Links