Warum gibt Boolean.ToString "True" und nicht "true" aus?

235
true.ToString() 
false.toString();

Output:
True
False

Gibt es einen gültigen Grund dafür, dass es "wahr" und nicht "wahr" ist? Es bricht beim Schreiben von XML ab, da der boolesche Typ von XML in Kleinbuchstaben geschrieben wird und auch nicht mit C #s true / false kompatibel ist (bei CLS jedoch nicht sicher).

Aktualisieren

Hier ist meine sehr hackige Art, es in C # zu umgehen (zur Verwendung mit XML)

internal static string ToXmlString(this bool b)
{
    return b.ToString().ToLower();
}

Das fügt dem Stapel natürlich eine weitere Methode hinzu, entfernt jedoch überall ToLowers ().

Chris S.
quelle
1
Ich dachte nur, ich würde das erwähnen ... Ich habe gerade eine clevere Problemumgehung gelesen, um "True" als booleschen Typ in C # in einem msdn-Blog zu deserialisieren! Siehe http://blogs.msdn.com/helloworld/archive/2009/04/03/workaround-to-deserialize-true-false-using-xmlserializer.aspx
Peter
23
Ich würde ersetzen return b.ToString().ToLower();mit return b ? "true" : "false";. Sauberer, effizienter, weniger abhängig von einer Methode, die theoretisch vom Gebietsschema abhängen könnte (obwohl dies in aktuellen Implementierungen nicht der Fall ist).
Jon Hanna
1
Dies ist auch ziemlich ärgerlich, wenn Sie mit RestSharp die öffentlichen Eigenschaften eines Objekts in einen QueryString serialisieren, um einen REST-WebService-Aufruf durchzuführen. Wenn bei der REST-API bei Bools zwischen Groß- und Kleinschreibung unterschieden wird (z. B. bei der Google Directions-API), schlägt der API-Aufruf fehl.
Carlos P
8
"ToString ist die wichtigste Formatierungsmethode in .NET Framework. Es konvertiert ein Objekt in seine Zeichenfolgendarstellung, sodass es für die Anzeige geeignet ist ." (Hervorhebung von mir). Object.ToString ist kein Serialisierungsmechanismus . :)
Rytmis
1
@awe yeah, das ist die Art von Erfahrung, die mich dazu bringt, mich gegen das theoretische Risiko zu schützen, obwohl es derzeit nicht passiert.
Jon Hanna

Antworten:

165

Nur Leute von Microsoft können diese Frage wirklich beantworten. Ich möchte jedoch einige lustige Fakten dazu anbieten;)

Zunächst wird in MSDN Folgendes über die Boolean.ToString () -Methode gesagt :

Rückgabewert

Typ: System.String

TrueString, wenn der Wert dieser Instanz true ist, oder FalseString, wenn der Wert dieser Instanz false ist.

Bemerkungen

Diese Methode gibt die Konstanten "True" oder "False" zurück. Beachten Sie, dass bei XML zwischen Groß- und Kleinschreibung unterschieden wird und dass die XML-Spezifikation "true" und "false" als gültigen Satz von Booleschen Werten erkennt. Wenn das von der ToString () -Methode zurückgegebene String-Objekt in eine XML-Datei geschrieben werden soll, sollte zuerst die String.ToLower-Methode aufgerufen werden, um es in Kleinbuchstaben zu konvertieren.

Hier kommt die lustige Tatsache Nr. 1: Sie gibt TrueString oder FalseString überhaupt nicht zurück. Es werden fest codierte Literale "True" und "False" verwendet. Würde Ihnen nichts nützen, wenn die Felder verwendet würden, da sie als schreibgeschützt markiert sind und daher nicht geändert werden.

Die alternative Methode Boolean.ToString (IFormatProvider) ist noch lustiger:

Bemerkungen

Der Provider-Parameter ist reserviert. Es ist nicht an der Ausführung dieser Methode beteiligt. Dies bedeutet, dass die Boolean.ToString-Methode (IFormatProvider) im Gegensatz zu den meisten Methoden mit einem Provider-Parameter keine kulturspezifischen Einstellungen widerspiegelt.

Was ist die Lösung? Kommt darauf an, was genau du versuchst zu tun. Was auch immer es ist, ich wette, es wird einen Hack erfordern;)

Vojislav Stojkovic
quelle
2
Korrigieren Sie mich, wenn ich falsch liege, aber ich sehe nichts falsches an der Erklärung für Boolean.ToString(). bool.TrueStringist ein schreibgeschütztes Feld, das das fest codierte Literal "True" enthält . Die Angabe, dass die Rückgabe erfolgt, entspricht der Angabe, dass das darin gespeicherte fest TrueStringcodierte Literal "True" zurückgegeben wird, da die Rückgabe einer Zeichenfolge immer den Wert und keine Referenz zurückgibt.
Fernando Neira
21
Das beobachtbare Ergebnis ist das gleiche. Die Implementierung ist nicht.
Vojislav Stojkovic
1
Das Kompilieren des C # würde den Boolean.TrueString in den kompilierten Ergebnissen nicht durch "True" ersetzen. Wenn sie tatsächlich Boolean.TrueString verwenden, können Sie Reflection verwenden, um Boolean.TrueString zu ändern und eine Kleinbuchstabenversion zurückzugeben ... natürlich, wer weiß, was das kaputt machen würde. Sie können Reflection weiterhin verwenden, um die ToString-Methode in Boolean zu ersetzen, sodass die Kleinbuchstabenvarianten zurückgegeben werden.
Dewey Vozel
2
@FernandoNeira, wenn morgen das fest codierte Literal TrueStringbeispielsweise in "true" in Kleinbuchstaben geändert wird, gibt die Methode bool.ToString()immer noch das Literal "True" in Pascal zurück.
Serge
1
Ich beschuldige Visual Basic, das True und False als Literalwerte verwendet.
Mrcrowl
105

... weil die .NET-Umgebung viele Sprachen unterstützt.

System.Boolean (in mscorlib.dll) wurde entwickelt, um intern von Sprachen verwendet zu werden, um einen booleschen Datentyp zu unterstützen. C # verwendet für seine Schlüsselwörter alle Kleinbuchstaben, daher 'bool', 'true' und 'false'.

VB.NET verwendet jedoch ein Standardgehäuse: daher 'Boolean', 'True' und 'False'.

Da die Sprachen zusammenarbeiten müssen, kann true.ToString () (C #) nicht vorhanden sein, wodurch True.ToString () (VB.NET) ein anderes Ergebnis erhält. Die CLR-Designer haben die Standard-CLR-Gehäusenotation für das ToString () - Ergebnis ausgewählt.

Die Zeichenfolgendarstellung des booleschen Wertes true ist als Boolean.TrueString definiert.

(Es gibt einen ähnlichen Fall bei System.String: C # präsentiert ihn als 'String'-Typ).

Stusmith
quelle
4
Sie mussten VB aus der Sicht der Dinge unterbringen
Chris S
5
Ich würde sagen, C # ist die "seltsame" Sprache. Alles, was in .NET öffentlich ist, ist CamelCase - System.Boolean, True, System.String usw. - es ist das C-Erbe von C #, das zum Aliasing von String zu String, Boolean zu Bool, True zu True usw. führt (obwohl meine persönliche Präferenz ist noch C #).
Stusmith
4
Darüber hinaus ist der gute Grund (für mich), in Kleinbuchstaben zu konvertieren, einfach, während es schwierig ist, CamelCase zu erstellen, insbesondere wenn VB verwendet wird, wie es @John Burns sagte. Andernfalls kann und wird der VB-Benutzer das nicht verwenden ToString()und er muss es gerne verwenden If(b, "True", "False"). Also c # Benutzer wie ich müssen opfern, um zu verwenden ToLower():)
CallMeLaNN
2
@MarkLopez Ihr Kommentar ist falsch, siehe hier: msdn.microsoft.com/en-us/library/c8f5xwh7.aspx . Wenn Sie die Boolesche Definition nachschlagen, sehen Sie, dass es sich tatsächlich um eine Struktur handelt und die beiden dieselben Eigenschaften haben.
Tsemer
1
Während Ihre Antwort etwas Licht ins Dunkel bringt, verstehe ich nicht, wie "Wahr" mehr "Standard" als "Wahr" ist. Letzteres scheint viel beliebter zu sein.
Geringfügige
50

Für Xml können Sie die XmlConvert.ToString- Methode verwenden.

bruno conde
quelle
4
Dies scheint bei weitem die eleganteste Methode zu sein. Keine zusätzliche Programmierung und Verwendung einer offiziellen Bibliothek, die tatsächlich für die XML-Ausgabe erstellt wurde.
Nyerguds
25

Es ist ein einfacher Code, um dies in Kleinbuchstaben umzuwandeln.

Es ist jedoch nicht so einfach, "true" wieder in "True" umzuwandeln.

true.ToString().ToLower() 

ist das, was ich für die XML-Ausgabe verwende.

John
quelle
Zusätzlich zur @ stusmith-Antwort, weil zur Unterstützung vieler Sprachen dies ein guter Grund ist, warum Microsoft das VB-Aussehen des booleschen ToString()Ergebnisses bevorzugt .
CallMeLaNN
@ Damieh: Eigentlich ist die Frage "Warum". Im Gegensatz dazu kommt die ausgewählte Antwort der Beantwortung so nahe wie möglich.
Nyerguds
1
Besser noch; ToLowerInvariant().
Vulkanischer Rabe
3
Sie können System.Globalization.CultureInfo.InvariantCulture.TextInfo.ToTitleCase verwenden, um "true" zurück in "True" zu konvertieren.
Jenny O'Reilly
8

Wie ist es nicht mit C # kompatibel? Bei Boolean.Parse und Boolean.TryParse wird die Groß- und Kleinschreibung nicht berücksichtigt. Bei der Analyse wird der Wert mit Boolean.TrueString oder Boolean.FalseString verglichen, die "True" und "False" sind.

BEARBEITEN: Wenn Sie sich die Boolean.ToString-Methode im Reflektor ansehen, stellt sich heraus, dass die Zeichenfolgen fest codiert sind, sodass die ToString-Methode wie folgt lautet:

public override string ToString()
{
    if (!this)
    {
        return "False";
    }
    return "True";
}
Rune Grimstad
quelle
23
Wow ... Das ist wahrscheinlich der einzige Kontext in C #, in dem das Konstrukt "if (! This)" gültig ist!
Tamas Czinege
2
Warum ist es nicht mehr zurück „false“ ist , was ich frage
Chris S
Was für eine seltsame Sache ... Ich meine, den Zustand umkehren.
nicodemus13
6
@TamasCzinege That's probably the only context in C# where the construct "if (!this)" is valid! Du hast mich herausgefordert, du verlierst . gist.github.com/Steinblock/10df18afb948866be1ba - Auch heute ist der 200. Geburtstag von George Boole
Jürgen Steinblock
Frage mich, warum das nicht so gemacht wurde return this ? "True" : "False";? (Ein weiterer ungewöhnlicher Fall, wie Sie nicht oft thisals ?:Bedingung sehen, aber hier würde es Sinn machen.)
Darrel Hoffman
7

Ich kenne den Grund, warum es so ist, wie es bereits angesprochen wurde, aber wenn es um "benutzerdefinierte" boolesche Formatierung geht, habe ich zwei Erweiterungsmethoden, ohne die ich nicht mehr leben kann :-)

public static class BoolExtensions
{
    public static string ToString(this bool? v, string trueString, string falseString, string nullString="Undefined") {
        return v == null ? nullString : v.Value ? trueString : falseString;
    }
    public static string ToString(this bool v, string trueString, string falseString) {
        return ToString(v, trueString, falseString, null);
    }
}

Die Verwendung ist trivial. Im Folgenden werden verschiedene Bool-Werte in ihre portugiesischen Darstellungen konvertiert:

string verdadeiro = true.ToString("verdadeiro", "falso");
string falso = false.ToString("verdadeiro", "falso");
bool? v = null;
string nulo = v.ToString("verdadeiro", "falso", "nulo");
Loudenvier
quelle
"Sie können Erweiterungsmethoden verwenden, um eine Klasse oder Schnittstelle zu erweitern, aber nicht, um sie zu überschreiben. Eine Erweiterungsmethode mit demselben Namen und derselben Signatur wie eine Schnittstelle oder Klassenmethode wird niemals aufgerufen. Zur Kompilierungszeit haben Erweiterungsmethoden immer eine niedrigere Priorität als Instanzmethoden, die im Typ selbst definiert sind. " Funktioniert Ihre Lösung? (Vielleicht wird ToString () geerbt und kann daher überschrieben werden?)
jwize
1
Ich denke zu meinem vorherigen Kommentar, diese Signatur überschreibt nichts.
Jwize
@jwize ja, das sind neue Signaturen, also ist es eine Überlastung, keine Überschreibung ;-)
Loudenvier
0

Der Grund truefür "True" liegt in der starken Bindung von Microsoft an XML-Standards.

Aus Wikipedia : "XML (Extensible Markup Language) ist eine Auszeichnungssprache, die eine Reihe von Regeln für die Codierung von Dokumenten in einem Format definiert, das sowohl für Menschen als auch für Maschinen lesbar ist."

Vom Menschen lesbar ist subjektiv, aber in den Augen von XML wird die Verwendung des Wortes "Eins" anstelle einer Zahl "1" bevorzugt. Sie werden feststellen, dass dies mithilfe von Aufzählungen geschieht, da das Wort anstelle seines Werts serialisiert wird ("FirstOption" anstelle von "0" oder "1").

Ebenso folgt der Text üblicherweise CamelCasing . Daher bevorzugt XML anstelle von "Zeichenfolge" "Zeichenfolge". Aus diesem Grund ist Boolean.TrueString "True" und Boolean.FalseString standardmäßig "False".

Kody
quelle
7
Lustig, dass der XML-Boolesche Wert nicht mehr funktioniert, wenn Sie ihn auf "True" und dann nicht auf "true" setzen? - "Beachten Sie, dass bei XML zwischen Groß- und Kleinschreibung unterschieden wird und dass die XML-Spezifikation" true "und" false "als gültigen Satz von Booleschen Werten
erkennt
-1

Dies geht wahrscheinlich auf die alten VB NOT .Net-Tage zurück, als bool.ToString True oder False produzierte.

cjk
quelle
3
Vor .NET verfügte der boolesche Datentyp in VB (tatsächlich alle Datentypen) nicht über Methoden.
Sam Axe
1
In VB6 können Sie den Booleschen Typ weiterhin in einen String konvertieren (einfachste Möglichkeit, ihn einer String-Variablen zuzuweisen). Das Seltsame daran war, dass die Konvertierung tatsächlich kulturspezifisch war. Wenn Ihre Kultursprache auf dem laufenden Computer also Norwegisch war, war das Ergebnis "Sann" und "Usann" anstelle von "True" und "False"! Dies verursachte häufig Probleme, wenn boolesche Einstellungen in einer Textdatei gespeichert und in eine andere Umgebung exportiert wurden, in der der Computer mit englischer (US) Kultur eingerichtet wurde.
Ehrfurcht