274
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.

Chris S
  • 64,770
  • 52
  • 221
  • 239
  • 32
    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). – Jon Hanna Sep 30 '10 at 13:09
  • 1
    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. – Carlos P Feb 18 '14 at 23:25
  • 9
    "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. :) – Rytmis Mar 01 '14 at 18:47
  • @JonHanna: Actually in the old VB6 world, the conversion *was* culture specific, which has caused me some strange headaches with export/import functionality where settings were stored in text file. It would cause wrong values if imported in a different locale than where it was exported. – awe Mar 20 '14 at 10:48
  • 1
    @awe yeah, that's the sort of experience that leads me to guard against the theoretical risk even though it doesn't currently happen. – Jon Hanna Mar 20 '14 at 17:59
  • 1
    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](http://blogs.msdn.com/helloworld/archive/2009/04/03/workaround-to-deserialize-true-false-using-xmlserializer.aspx) – Peter Sep 03 '09 at 13:27
  • If you happen to be using the strings for JSON or javascript, e.g. for the value of a `data-` attribute, you can use JSON.net's `JsonConvert.ToString(bool)` method, which feels more conceptually correct and concise to me than `.ToString().ToLower()` despite being more characters. – xr280xr Dec 20 '18 at 20:40

7 Answers7

186

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

Vojislav Stojkovic
  • 8,043
  • 4
  • 35
  • 48
  • 2
    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. – Fernando Neira Feb 15 '12 at 10:22
  • 25
    The observable result is the same. The implementation is not. – Vojislav Stojkovic Feb 16 '12 at 11:23
  • I assume you know that by using a decompiler, so I could bet that the literals appear because the compiler substituted the variables when compiling... except for the fact that _TrueString_ is not a constant, but just a readonly - important detail -. Therefore, you are right. – Fernando Neira Feb 16 '12 at 14:04
  • 1
    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. – Dewey Vozel Mar 28 '14 at 14:59
  • 2
    @FernandoNeira, if tomorrow the hardcoded literal `TrueString` be changed, say, to lowercase "true", the method `bool.ToString()` will still return pascal case "True" literal. – serge Apr 20 '16 at 09:15
  • 4
    I blame Visual Basic, which uses True and False as its literal values. – mrcrowl Mar 01 '19 at 10:45
113

...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).

stusmith
  • 14,003
  • 7
  • 56
  • 89
  • 6
    They had to accommodate VB from the looks of things – Chris S Jan 29 '09 at 12:31
  • 5
    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#). – stusmith Jan 29 '09 at 13:17
  • 4
    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()` :) – CallMeLaNN Jul 11 '11 at 10:13
  • +1 for pointing out the language-agnostic requirement. This ought to be the accepted answer. – Caleb Bell Oct 22 '13 at 17:11
  • 2
    @MarkLopez Your comment is incorrect, see here: http://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. – tsemer Aug 13 '14 at 06:52
  • 2
    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. – Slight Apr 29 '15 at 15:17
  • Just for those interested Microsoft interprets camelCasing (asInFirstLetterIsLower) PascalCasing (AsInEveryWordStartsWithCapitals). I prefer the retrofitted word camelCasing to fit Microsoft's description. – jwize Oct 06 '15 at 16:36
  • This answer is the right one. Its the language agnostic requirement, C# is the odd language here indeed. – Julian Mar 08 '17 at 22:08
  • 1
    What language(s) other than VB use "True"? C, C#, PHP, java, javascript all use true. – Robert McKee Jan 13 '22 at 16:57
60

For Xml you can use XmlConvert.ToString method.

bruno conde
  • 47,767
  • 15
  • 98
  • 117
  • 6
    This seems by far the most elegant method. No extra programming, and using an official library actually created for the purpose of xml output. – Nyerguds Dec 05 '13 at 10:40
30

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.

Joe the Person
  • 4,470
  • 3
  • 22
  • 32
John
  • 5,672
  • 7
  • 34
  • 52
  • 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. – CallMeLaNN Jul 11 '11 at 06:59
  • @Damieh: actually, the question is "Why". The selected answer, unlike this, actually comes as close to answering that as it can. – Nyerguds Dec 05 '13 at 10:37
  • 1
    Better yet; `ToLowerInvariant()`. – vulcan raven Jul 13 '14 at 12:49
  • 3
    You can use System.Globalization.CultureInfo.InvariantCulture.TextInfo.ToTitleCase to convert "true" back to "True". – Krisztián Balla Nov 11 '14 at 08:32
  • @vulcanraven this absolutely does not matter in this case at all. Boolean.ToString() always returns "True" or "False" which work perfectly without Invariant. – GoldenretriverYT Mar 09 '23 at 11:24
  • @GoldenretriverYT, see the [codegen](https://sharplab.io/#v2:EYLgxg9gTgpgtADwGwBYA0AXEBDAzgWwB8BiAOwFcAbS7YSmAAgBMBLXW+gWACgABAZga8ATAwDCDAN48GsoYN4BGAAwMAsooAUASgYBeAHwMMUcjAB0AFQgBlEy1IBzHVYgAZCAHcYUHQG4ZOQEhFXVhHX0jEzNXOygHZ21XD28oAElSADdseOxSDH8eAF8gA==); `ToLower()` makes additional calls to `GetCurrentThreadNative()` and `get_CurrentCulture()` which you can save with `ToLowerInvariant()`. – vulcan raven Mar 26 '23 at 09:42
8

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";
}
Rune Grimstad
  • 35,612
  • 10
  • 61
  • 76
  • 26
    Wow... That's probably the only context in C# where the construct "if (!this)" is valid! – Tamas Czinege Jan 29 '09 at 12:17
  • 2
    so why isn't it return "false" is what I'm asking – Chris S Jan 29 '09 at 12:18
  • 1
    What a weird thing to do... I mean invert the condition. – nicodemus13 Sep 29 '15 at 10:22
  • 6
    @TamasCzinege `That's probably the only context in C# where the construct "if (!this)" is valid! ` You challenged me, you loose. https://gist.github.com/Steinblock/10df18afb948866be1ba - Also today is the 200th birtday of George Boole – Jürgen Steinblock Nov 02 '15 at 13:26
  • 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.) – Darrel Hoffman Dec 21 '18 at 18:48
7

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");
Loudenvier
  • 8,362
  • 6
  • 45
  • 66
  • "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?) – jwize Oct 06 '15 at 16:38
  • 1
    I guess to my previous comment this signature is not overriding anything. – jwize Oct 06 '15 at 16:48
  • @jwize yes, these are new signatures, so it's an overload not an override ;-) – Loudenvier Oct 08 '15 at 22:32
-1

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

cjk
  • 45,739
  • 9
  • 81
  • 112
  • 4
    Prior to .NET the Boolean data type in VB (in fact, all data types) did not have methods. – Sam Axe May 05 '09 at 01:55
  • 1
    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. – awe Mar 20 '14 at 10:37