2009-01-29 18 views
193
true.ToString() 
false.toString(); 

Output: 
True 
False 

¿Hay alguna razón válida para que sea "Verdadero" y no "verdadero"? Se rompe al escribir XML como el tipo booleano de XML en minúsculas, y tampoco es compatible con C# 's verdadero/falso (aunque no estoy seguro acerca de CLS).¿Por qué la salida Boolean.ToString es "Verdadera" y no "verdadera"

actualización

Aquí está mi manera poco limpia de conseguir alrededor de él en C# (para su uso con XML)

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

Por supuesto que añade 1 método más para la pila, pero elimina ToLowers() en todos lados.

+21

Reemplazaría 'return b.ToString(). ToLower();' con 'return b? "verdadero": "falso"; '. 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 haga en las implementaciones actuales). –

+0

Me alegra que no soy el único que estaba totalmente confundido y molesto por esto. Por cierto, estoy lidiando con el mismo problema. (Se está rompiendo mi XML) – Chris

+1

Esto también es bastante molesto cuando se utiliza RestSharp para serializar las propiedades públicas de un objeto en QueryString para realizar una llamada a REST WebService. Si la API REST distingue entre mayúsculas y minúsculas para los bools (por ejemplo, la API de Google Directions), esto hace que falle la llamada API. –

Respuesta

136

Solo las personas de Microsoft pueden responder esa pregunta. Sin embargo, me gustaría ofrecer algunos datos curiosos sobre él;)

En primer lugar, esto es lo que dice en MSDN sobre el método Boolean.toString():

Valor devuelto

Tipo: Sistema.Cadena

TrueString si el valor de este instancia es cierto, o FalseString si el valor de esta instancia es falsa.

Observaciones

Este método devuelve el 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() debe escribirse en un archivo XML, su método String.ToLower debe ser llamado primero para convertirlo a en minúscula.

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

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

Observaciones

El parámetro 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 las configuraciones específicas de la cultura.

¿Cuál es la solución? Depende de qué estás tratando de hacer exactamente. Sea lo que sea, apuesto a que requerirá un hack;)

+1

Corrígeme si me equivoco, pero no veo nada de malo en la explicación de 'Boolean.ToString()'. 'bool.TrueString' es un campo de solo lectura que contiene el literal codificado _" Verdadero "_. Por lo tanto, decir que devuelve 'TrueString' es 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. –

+18

El resultado observable es el mismo. La implementación no es –

+0

Supongo que sabes que al usar un descompilador, entonces podría apostar que los literales aparecen porque el compilador sustituyó las variables al compilar ... excepto por el hecho de que _TrueString_ no es una constante, sino simplemente un detalle importante. Por lo tanto, tienes razón. –

6

¿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 hace comparando el valor con Boolean.TrueString o Boolean.FalseString que son "True" y "False".

EDIT: Al mirar el método Boolean.toString en el reflector resulta que las cuerdas están codificados por lo que el método ToString es el siguiente:

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

Wow ... Ese es probablemente el único contexto en C# donde el constructo "if (! this)" es válido. –

+2

Entonces, ¿por qué no se devuelve "falso" es lo que estoy preguntando –

+0

Por qué es difícil de decir. Probablemente por casualidad en realidad ... –

16

Es simple código para convertir a que todo en minúsculas .

No es tan sencillo convertir "verdadero" en "Verdadero", sin embargo.

true.ToString().ToLower() 

es lo que uso para la salida xml.

+0

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 booleano ' ToString() 'resultado. – CallMeLaNN

+0

@Damieh: en realidad, la pregunta es "por qué". La respuesta seleccionada, a diferencia de esto, en realidad está tan cerca de responder eso como pueda. – Nyerguds

+1

Mejor aún; 'ToLowerInvariant()'. –

38

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

+3

Este parece por lejos el método más elegante. Sin programación adicional, y el uso de una biblioteca oficial realmente creada con el propósito de salida xml. – Nyerguds

96

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

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

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

Como los idiomas 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 escogieron la notación de carcasa CLR estándar para el resultado de ToString().

La cadena de caracteres del booleano true se define como Boolean.TrueString.

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

+3

Tenían que acomodar a VB desde el aspecto de las cosas –

+5

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 el patrimonio C de C# lo que lleva al aliasing de String a string, Boolean a bool, True a true, etc. (Aunque mi preferencia personal es aún C#). – stusmith

+3

Además, la buena razón (para mí) es 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 usar nunca el 'ToString()' y lo forzaron a usar como 'If (b," True "," False ")'. Entonces, el usuario de C# como yo debe sacrificarse para usar 'ToLower()' :) – CallMeLaNN

-1

Esto probablemente proviene de los viejos VB NO días .Net cuando bool.ToString produjo verdadero o falso.

+3

Antes de .NET, el tipo de datos booleanos en VB (de hecho, todos los tipos de datos) no tenía métodos. –

+1

En VB6, aún puede convertir el tipo booleano en cadena (la forma más sencilla de asignarlo a una variable String). Lo extraño de esto fue que la conversión era culturalmente específica, así que si tu idioma de cultura en la computadora en ejecución era noruego, el resultado sería "Sann" y "Usann" en lugar de "Verdadero" y "Falso". Esto a menudo causaba problemas si las configuraciones booleanas se almacenaban en un archivo de texto y se exportaban a un entorno diferente donde la computadora estaba configurada con una cultura en inglés (EE. UU.). – awe

5

Conozco el motivo por el que ya se ha abordado, pero cuando se trata de formatear booleanos "personalizados", tengo dos métodos de extensión 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. A continuación se 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"); 
+0

"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 tiempo de compilación, los métodos de extensión siempre tienen menor prioridad que los métodos de instancia definidos en el tipo en sí ". ¿Funciona su solución? (Tal vez ToString() se hereda, por lo tanto, puede ser reemplazado?) – jwize

+1

Supongo que para mi comentario anterior esta firma no está anulando nada. – jwize

+0

@jwize sí, estas son firmas nuevas, por lo que es una sobrecarga, no una anulación ;-) – Loudenvier

0

La razón true es "verdad" es debido a la fuerte unión de Microsoft con los estándares XML.

De Wikipedia: "Extensible Markup Language (XML) es un lenguaje de marcado que define un conjunto de reglas de codificación de documentos en un formato que es a la vez legible y legible por la máquina."

legible por humanos es subjetivo, pero a los ojos de XML, se prefiere usar la palabra "Uno" en lugar del número "1". Notarás 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 suele seguir CamelCasing. Por lo tanto, en lugar de "cadena", XML prefiere "Cadena". Esta es la razón por la cual Boolean.TrueString es "True" y Boolean.FalseString es "False" por defecto.

+6

¿Gracioso que booleano XML se romperá si lo configuras en "True" y no "true" 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

Cuestiones relacionadas