ChatGPT解决这个技术问题 Extra ChatGPT

Why does Boolean.ToString output "True" and not "true"

true.ToString() 
false.toString();

Output:
True
False

Is there a valid reason for it being "True" and not "true"? It breaks when writing XML as XML's boolean type is lower case, and also isn't compatible with C#'s true/false (not sure about CLS though).

Update

Here is my very hacky way of getting around it in C# (for use with XML)

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

Of course that adds 1 more method to the stack, but removes ToLowers() everywhere.

Just thought I'd mention this... I've just read some clever workaround to deserialize "True" as a boolean type in C# on an msdn blog! see http://blogs.msdn.com/helloworld/archive/2009/04/03/workaround-to-deserialize-true-false-using-xmlserializer.aspx
I'd replace return b.ToString().ToLower(); with return b ? "true" : "false";. Cleaner, more efficient, less dependant on a method that theoretically could depend on locale (even though it doesn't in current implementations).
This is also quite annoying when using RestSharp to serialize the public properties of an object into a QueryString to make a REST WebService call. If the REST API is case-sensitive for bools (e.g. the Google Directions API) then this causes the API call to fail.
"ToString is the major formatting method in the .NET Framework. It converts an object to its string representation so that it is suitable for display." (Emphasis mine). Object.ToString is not a serialization mechanism. :)
@awe yeah, that's the sort of experience that leads me to guard against the theoretical risk even though it doesn't currently happen.

V
Vojislav Stojkovic

Only people from Microsoft can really answer that question. However, I'd like to offer some fun facts about it ;)

First, this is what it says in MSDN about the Boolean.ToString() method:

Return Value Type: System.String TrueString if the value of this instance is true, or FalseString if the value of this instance is false. Remarks This method returns the constants "True" or "False". Note that XML is case-sensitive, and that the XML specification recognizes "true" and "false" as the valid set of Boolean values. If the String object returned by the ToString() method is to be written to an XML file, its String.ToLower method should be called first to convert it to lowercase.

Here comes the fun fact #1: it doesn't return TrueString or FalseString at all. It uses hardcoded literals "True" and "False". Wouldn't do you any good if it used the fields, because they're marked as readonly, so there's no changing them.

The alternative method, Boolean.ToString(IFormatProvider) is even funnier:

Remarks The provider parameter is reserved. It does not participate in the execution of this method. This means that the Boolean.ToString(IFormatProvider) method, unlike most methods with a provider parameter, does not reflect culture-specific settings.

What's the solution? Depends on what exactly you're trying to do. Whatever it is, I bet it will require a hack ;)


Correct me if I'm wrong, but I don't see anything wrong with the explanation for Boolean.ToString(). bool.TrueString is a read-only field that contains the hardcoded literal "True". Therefore, saying that it returns TrueString is the same as saying it returns the hardcoded literal "True" stored in it, given that returning a string always returns the value and not a reference.
The observable result is the same. The implementation is not.
Compiling the C# wouldn't replace the Boolean.TrueString with "True" in the compiled results. If they actually made use of Boolean.TrueString then you could use reflection to change Boolean.TrueString to return a lowercase version... of course who knows what that would break. You could still use reflection to replace the ToString method on Boolean so that it returns the lower case variants.
@FernandoNeira, if tomorrow the hardcoded literal TrueString be changed, say, to lowercase "true", the method bool.ToString() will still return pascal case "True" literal.
I blame Visual Basic, which uses True and False as its literal values.
s
stusmith

...because the .NET environment is designed to support many languages.

System.Boolean (in mscorlib.dll) is designed to be used internally by languages to support a boolean datatype. C# uses all lowercase for its keywords, hence 'bool', 'true', and 'false'.

VB.NET however uses standard casing: hence 'Boolean', 'True', and 'False'.

Since the languages have to work together, you couldn't have true.ToString() (C#) giving a different result to True.ToString() (VB.NET). The CLR designers picked the standard CLR casing notation for the ToString() result.

The string representation of the boolean true is defined to be Boolean.TrueString.

(There's a similar case with System.String: C# presents it as the 'string' type).


They had to accommodate VB from the looks of things
I would say C# is the "odd" language. Everything public in .NET is CamelCase - System.Boolean, True, System.String, etc - it's C#'s C heritage that lead to the aliasing of String to string, Boolean to bool, True to true, etc. (Although my personal preference is still C#).
Additionally, the good reason (for me) is converting to lower case is easy while it is hard to make it CamelCase especially when VB is used just like @John Burns said. Otherwise VB user cannot and will never use the ToString() and they forced to use like If(b, "True", "False"). So c# user like me need to sacrifice to use ToLower() :)
@MarkLopez Your comment is incorrect, see here: msdn.microsoft.com/en-us/library/c8f5xwh7.aspx. Also, looking up the Boolean definition reveals it is in fact a struct, and the two do have the same properties.
While your answer sheds some light, I don't understand how "True" is more "standard" than "true". It seems like the latter is much more popular.
b
bruno conde

For Xml you can use XmlConvert.ToString method.


This seems by far the most elegant method. No extra programming, and using an official library actually created for the purpose of xml output.
J
Joe the Person

It's simple code to convert that to all lower case.

Not so simple to convert "true" back to "True", however.

true.ToString().ToLower() 

is what I use for xml output.


In addition of @stusmith answer because to support for many languages, this is nice reason why Microsoft prefer VB look of the boolean ToString() result.
@Damieh: actually, the question is "Why". The selected answer, unlike this, actually comes as close to answering that as it can.
Better yet; ToLowerInvariant().
You can use System.Globalization.CultureInfo.InvariantCulture.TextInfo.ToTitleCase to convert "true" back to "True".
R
Rune Grimstad

How is it not compatible with C#? Boolean.Parse and Boolean.TryParse is case insensitive and the parsing is done by comparing the value to Boolean.TrueString or Boolean.FalseString which are "True" and "False".

EDIT: When looking at the Boolean.ToString method in reflector it turns out that the strings are hard coded so the ToString method is as follows:

public override string ToString()
{
    if (!this)
    {
        return "False";
    }
    return "True";
}

Wow... That's probably the only context in C# where the construct "if (!this)" is valid!
so why isn't it return "false" is what I'm asking
What a weird thing to do... I mean invert the condition.
@TamasCzinege That's probably the only context in C# where the construct "if (!this)" is valid! You challenged me, you loose. gist.github.com/Steinblock/10df18afb948866be1ba - Also today is the 200th birtday of George Boole
Wonder why this wasn't done as return this ? "True" : "False";? (Another unusual case as you don't often see this as a ?: condition, but here it would make sense.)
L
Loudenvier

I know the reason why it is the way it is has already been addressed, but when it comes to "custom" boolean formatting, I've got two extension methods that I can't live without anymore :-)

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);
    }
}

Usage is trivial. The following converts various bool values to their Portuguese representations:

string verdadeiro = true.ToString("verdadeiro", "falso");
string falso = false.ToString("verdadeiro", "falso");
bool? v = null;
string nulo = v.ToString("verdadeiro", "falso", "nulo");

"You can use extension methods to extend a class or interface, but not to override them. An extension method with the same name and signature as an interface or class method will never be called. At compile time, extension methods always have lower priority than instance methods defined in the type itself." Does your solution work?(maybe ToString() is inherited therefore can be overriden?)
I guess to my previous comment this signature is not overriding anything.
@jwize yes, these are new signatures, so it's an overload not an override ;-)
c
cjk

This probably harks from the old VB NOT .Net days when bool.ToString produced True or False.


Prior to .NET the Boolean data type in VB (in fact, all data types) did not have methods.
In VB6, you could still convert Boolean type to string (simplest way to assign it to a String variable). The strange thing about this, was that the conversion was actually culture specific, so if your culture language on the running computer was Norwegian, the result was "Sann" and "Usann" instead of "True" and "False"! This often caused problems if boolean settings were stored in a text file, and exported to a different environment where the computer was set up with English(US) culture.
K
Kemboi
    public bool CheckBool(string res)
    {
        if (res == null)
        {
            return false;
        }

        if (res.ToLower() == "true")
        {
            return true;
        }
        if (res.ToLower() == "false")
        {
            return false;
        }
        if (res == "0")
        {
            return false;
        }
        if (res == "1")
        {
            return true;
        }
        else
        {
            return bool.Parse(res);
        }
    }