¿Por qué Boolean.ToString muestra "True" y no "true"?

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

Output:
True
False

¿Hay alguna razón válida para que sea "Verdadero" y no "verdadero"? Se rompe cuando se escribe XML, ya que el tipo booleano de XML es minúscula y tampoco es compatible con C / 'verdadero / falso (aunque no estoy seguro acerca de CLS).

Actualizar

Aquí está mi manera muy hacky de evitarlo en C # (para usar con XML)

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

Por supuesto, eso agrega 1 método más a la pila, pero elimina ToLowers () en todas partes.

Chris S
fuente
1
Solo pensé en mencionar esto ... ¡Acabo de leer una solución inteligente para deserializar "True" como un tipo booleano en C # en un blog msdn! ver http://blogs.msdn.com/helloworld/archive/2009/04/03/workaround-to-deserialize-true-false-using-xmlserializer.aspx
Peter
23
Lo reemplazaría return b.ToString().ToLower();con return b ? "true" : "false";. Más limpio, más eficiente, menos dependiente de un método que teóricamente podría depender de la configuración regional (aunque no lo hace en las implementaciones actuales).
Jon Hanna
1
Esto también es bastante molesto cuando se usa RestSharp para serializar las propiedades públicas de un objeto en un QueryString para realizar una llamada REST WebService. Si la API REST distingue entre mayúsculas y minúsculas para los bools (p. Ej., La API de Google Directions), esto hace que la llamada a la API falle.
Carlos P
8
"ToString es el principal método de formato en .NET Framework. Convierte un objeto en su representación de cadena para que sea adecuado para su visualización ". (El énfasis es mío). Object.ToString no es un mecanismo de serialización . :)
Rytmis
1
@awe sí, ese es el tipo de experiencia que me lleva a protegerme contra el riesgo teórico a pesar de que actualmente no sucede.
Jon Hanna

Respuestas:

165

Solo las personas de Microsoft realmente pueden responder esa pregunta. Sin embargo, me gustaría ofrecer algunos datos divertidos al respecto;)

Primero, esto es lo que dice en MSDN sobre el método Boolean.ToString () :

Valor de retorno

Tipo: System.String

TrueString si el valor de esta instancia es verdadero, o FalseString si el valor de esta instancia es falso.

Observaciones

Este método devuelve las constantes "Verdadero" o "Falso". Tenga en cuenta que XML distingue entre mayúsculas y minúsculas, y que la especificación XML reconoce "verdadero" y "falso" como el conjunto válido de valores booleanos. Si el objeto String devuelto por el método ToString () se va a escribir en un archivo XML, primero se debe llamar a su método String.ToLower para convertirlo a minúsculas.

Aquí viene el hecho divertido # 1: no devuelve TrueString o FalseString en absoluto. Utiliza literales codificados "Verdadero" y "Falso". No te haría ningún bien si usara los campos, porque están marcados como de solo lectura, por lo que no hay que cambiarlos.

El método alternativo, Boolean.ToString (IFormatProvider) es aún más divertido:

Observaciones

El parámetro del proveedor está reservado. No participa en la ejecución de este método. Esto significa que el método Boolean.ToString (IFormatProvider), a diferencia de la mayoría de los métodos con un parámetro de proveedor, no refleja la configuración específica de la cultura.

¿Cual es la solución? Depende de qué es exactamente lo que intentas hacer. Sea lo que sea, apuesto a que requerirá un hack;)

Vojislav Stojkovic
fuente
2
Corrígeme si me equivoco, pero no veo nada malo en la explicación Boolean.ToString(). bool.TrueStringes un campo de solo lectura que contiene el literal codificado "Verdadero" . Por lo tanto, decir que devuelve TrueStringes lo mismo que decir que devuelve el literal codificado "True" almacenado en él, dado que devolver una cadena siempre devuelve el valor y no una referencia.
Fernando Neira
21
El resultado observable es el mismo. La implementación no lo es.
Vojislav Stojkovic
1
Compilar el C # no reemplazaría el Boolean.TrueString con "True" en los resultados compilados. Si realmente hicieron uso de Boolean.TrueString, entonces podría usar la reflexión para cambiar Boolean.TrueString para devolver una versión en minúsculas ... por supuesto, quién sabe qué rompería. Todavía podría usar la reflexión para reemplazar el método ToString en Boolean para que devuelva las variantes en minúsculas.
Dewey Vozel
2
@FernandoNeira, si mañana TrueStringse cambia el literal codificado , digamos, a "verdadero" en minúsculas, el método bool.ToString()seguirá devolviendo el caso pascal "Verdadero".
Serge
1
Culpo a Visual Basic, que usa Verdadero y Falso como sus valores literales.
mrcrowl
105

... porque el entorno .NET está diseñado para admitir muchos idiomas.

System.Boolean (en mscorlib.dll) está diseñado para ser utilizado internamente por idiomas para admitir un tipo de datos booleano. C # usa todas las minúsculas para sus palabras clave, por lo tanto, 'bool', 'true' y 'false'.

Sin embargo, VB.NET utiliza una carcasa estándar: de ahí 'Boolean', 'True' y 'False'.

Dado que los lenguajes tienen que funcionar juntos, no podría tener true.ToString () (C #) dando un resultado diferente a True.ToString () (VB.NET). Los diseñadores de CLR eligieron la notación de carcasa CLR estándar para el resultado ToString ().

La representación de cadena del verdadero booleano se define como Boolean.TrueString.

(Hay un caso similar con System.String: C # lo presenta como el tipo 'string').

stusmith
fuente
44
Tenían que acomodar a VB desde el aspecto de las cosas
Chris S
55
Yo diría que C # es el lenguaje "extraño". Todo lo público en .NET es CamelCase - System.Boolean, True, System.String, etc. - es la herencia de C # 'C que conduce al alias de String a string, Boolean a bool, True a true, etc. (Aunque mi preferencia personal es Todavía C #).
stusmith
44
Además, la buena razón (para mí) es que la conversión a minúsculas es fácil, mientras que es difícil hacerlo CamelCase, especialmente cuando se usa VB, como dijo @John Burns. De lo contrario, el usuario de VB no puede y nunca usará el ToString()y se obligó a usar like If(b, "True", "False"). Así que el usuario de C # como yo necesito sacrificarme para usar ToLower():)
CallMeLaNN
2
@MarkLopez Su comentario es incorrecto, consulte aquí: msdn.microsoft.com/en-us/library/c8f5xwh7.aspx . Además, al buscar la definición booleana se revela que, de hecho, es una estructura, y los dos tienen las mismas propiedades.
tsemer
1
Si bien su respuesta arroja algo de luz, no entiendo cómo "Verdadero" es más "estándar" que "verdadero". Parece que este último es mucho más popular.
Ligero
50

Para Xml puede usar el método XmlConvert.ToString .

bruno conde
fuente
44
Este parece, con mucho, el método más elegante. Sin programación adicional, y usando una biblioteca oficial realmente creada con el propósito de generar xml.
Nyerguds
25

Es un código simple para convertir eso en minúsculas.

Sin embargo, no es tan simple convertir "verdadero" a "verdadero".

true.ToString().ToLower() 

es lo que uso para la salida xml.

Juan
fuente
Además de la respuesta @stusmith porque es compatible con muchos idiomas, esta es una buena razón por la cual Microsoft prefiere el aspecto VB del ToString()resultado booleano .
CallMeLaNN
@Damieh: en realidad, la pregunta es "¿Por qué"? La respuesta seleccionada, a diferencia de esta, en realidad está tan cerca de responderla como puede.
Nyerguds
1
Mejor todavía; ToLowerInvariant().
cuervo vulcano
3
Puede usar System.Globalization.CultureInfo.InvariantCulture.TextInfo.ToTitleCase para convertir "verdadero" de nuevo a "Verdadero".
Jenny O'Reilly
8

¿Cómo no es compatible con C #? Boolean.Parse y Boolean. TryParse no distingue entre mayúsculas y minúsculas y el análisis se realiza comparando el valor con Boolean.TrueString o Boolean.FalseString, que son "True" y "False".

EDITAR: Al mirar el método Boolean.ToString en el reflector, resulta que las cadenas están codificadas por lo que el método ToString es el siguiente:

public override string ToString()
{
    if (!this)
    {
        return "False";
    }
    return "True";
}
Runa Grimstad
fuente
23
Wow ... ¡Ese es probablemente el único contexto en C # donde la construcción "if (! This)" es válida!
Tamas Czinege
2
¿por qué no se lo devolverá "falsa" es lo que estoy pidiendo
Chris S
Qué cosa más extraña hacer ... quiero decir invertir la condición.
nicodemus13
66
@TamasCzinege That's probably the only context in C# where the construct "if (!this)" is valid! Me desafiaste, perdiste . gist.github.com/Steinblock/10df18afb948866be1ba - También hoy es el cumpleaños número 200 de George Boole
Jürgen Steinblock
Me pregunto por qué no se hizo esto return this ? "True" : "False";. (Otro caso inusual, ya que a menudo no se ve thiscomo una ?:condición, pero aquí tendría sentido).
Darrel Hoffman
7

Sé que la razón por la cual ya se ha abordado, pero cuando se trata de formato booleano "personalizado", tengo dos métodos de extensión sin los que ya no puedo vivir :-)

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

El uso es trivial. Lo siguiente convierte varios valores bool a sus representaciones portuguesas:

string verdadeiro = true.ToString("verdadeiro", "falso");
string falso = false.ToString("verdadeiro", "falso");
bool? v = null;
string nulo = v.ToString("verdadeiro", "falso", "nulo");
Loudenvier
fuente
"Puede usar métodos de extensión para extender una clase o interfaz, pero no para anularlos. Nunca se llamará a un método de extensión con el mismo nombre y firma que una interfaz o método de clase. En el momento de la compilación, los métodos de extensión siempre tienen menor prioridad que métodos de instancia definidos en el tipo mismo ". ¿Funciona su solución? (Tal vez ToString () se hereda, por lo tanto, ¿se puede anular?)
jwize
1
Supongo que en mi comentario anterior esta firma no anula nada.
jwize
@jwize sí, estas son nuevas firmas, por lo que es una sobrecarga, no una anulación ;-)
Loudenvier
0

La razón truees "verdadera" es por el fuerte vínculo de Microsoft con los estándares XML.

De Wikipedia : "Extensible Markup Language (XML) es un lenguaje de marcado que define un conjunto de reglas para codificar documentos en un formato que es legible por humanos y por máquina".

La lectura humana es subjetiva, pero a los ojos de XML, se prefiere usar la palabra "Uno" en lugar del número "1". Notará que esto sucede usando enumeraciones, ya que la palabra se serializa en lugar de su valor ("FirstOption" en lugar de "0" o "1").

Del mismo modo, el texto sigue comúnmente a CamelCasing . Por lo tanto, en lugar de "cadena", XML prefiere "Cadena". Es por eso que Boolean.TrueString es "True" y Boolean.FalseString es "False" de forma predeterminada.

Kody
fuente
77
¿Es curioso que el booleano XML se rompa si lo configura en "Verdadero" y no "verdadero" entonces? - "Tenga en cuenta que XML distingue entre mayúsculas y minúsculas, y que la especificación XML reconoce" verdadero "y" falso "como el conjunto válido de valores booleanos"
PandaWood
-1

Esto probablemente se refiere a los viejos días de VB NOT .Net cuando bool.ToString produjo True o False.

cjk
fuente
3
Antes de .NET, el tipo de datos booleanos en VB (de hecho, todos los tipos de datos) no tenía métodos.
Sam Axe
1
En VB6, aún podría convertir el tipo booleano en cadena (la forma más simple de asignarlo a una variable de cadena). Lo extraño de esto es que la conversión fue en realidad específica de la cultura, por lo que si su idioma de la cultura en la computadora en ejecución era noruego, ¡el resultado fue "Sann" y "Usann" en lugar de "Verdadero" y "Falso"! Esto a menudo causaba problemas si la configuración booleana se almacenaba en un archivo de texto y se exportaba a un entorno diferente donde la computadora estaba configurada con la cultura inglesa (EE. UU.).
asombro