Perché Boolean.ToString produce "True" e non "true"


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

Output:
True
False

C'è un motivo valido per essere "Vero" e non "vero"? Si interrompe quando si scrive XML come il tipo booleano di XML è minuscolo e inoltre non è compatibile con true / false di C # (non sono sicuro di CLS).

Aggiornare

Ecco il mio modo molto confuso di aggirarlo in C # (per l'uso con XML)

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

Ovviamente ciò aggiunge un altro metodo allo stack, ma rimuove ToLowers () ovunque.


1
Ho pensato di menzionarlo ... Ho appena letto una soluzione intelligente per deserializzare "True" come tipo booleano in C # su un blog msdn! vedi http://blogs.msdn.com/helloworld/archive/2009/04/03/workaround-to-deserialize-true-false-using-xmlserializer.aspx
Peter

23
Sostituirei return b.ToString().ToLower();con return b ? "true" : "false";. Più pulito, più efficiente, meno dipendente da un metodo che teoricamente potrebbe dipendere dalle impostazioni locali (anche se non nelle implementazioni attuali).
Jon Hanna,

1
Questo è anche abbastanza fastidioso quando si utilizza RestSharp per serializzare le proprietà pubbliche di un oggetto in un QueryString per effettuare una chiamata REST WebService. Se l'API REST fa distinzione tra maiuscole e minuscole per i bool (ad esempio l'API di Google Directions), la chiamata API non riesce.
Carlos P,

8
"ToString è il principale metodo di formattazione in .NET Framework. Converte un oggetto nella sua rappresentazione di stringa in modo che sia adatto per la visualizzazione ." (Enfasi mia). Object.ToString non è un meccanismo di serializzazione . :)
Rytmis

1
@awe sì, questo è il tipo di esperienza che mi porta a proteggermi dal rischio teorico anche se al momento non accade.
Jon Hanna,

Risposte:


165

Solo le persone Microsoft possono davvero rispondere a questa domanda. Tuttavia, vorrei offrire alcuni fatti divertenti al riguardo;)

Innanzitutto, questo è ciò che dice in MSDN sul metodo Boolean.ToString () :

Valore di ritorno

Tipo: System.String

TrueString se il valore di questa istanza è vero o FalseString se il valore di questa istanza è falso.

Osservazioni

Questo metodo restituisce le costanti "Vero" o "Falso". Si noti che XML fa distinzione tra maiuscole e minuscole e che la specifica XML riconosce "true" e "false" come l'insieme valido di valori booleani. Se l'oggetto String restituito dal metodo ToString () deve essere scritto in un file XML, è necessario prima chiamare il suo metodo String.ToLower per convertirlo in minuscolo.

Ecco il fatto divertente n. 1: non restituisce TrueString o FalseString. Utilizza letterali hardcoded "True" e "False". Non ti farebbe nulla di buono se usasse i campi, perché sono contrassegnati come di sola lettura, quindi non è possibile cambiarli.

Il metodo alternativo, Boolean.ToString (IFormatProvider) è ancora più divertente:

Osservazioni

Il parametro del provider è riservato. Non partecipa all'esecuzione di questo metodo. Ciò significa che il metodo Boolean.ToString (IFormatProvider), a differenza della maggior parte dei metodi con un parametro provider, non riflette le impostazioni specifiche della cultura.

Qual è la soluzione? Dipende da cosa stai esattamente cercando di fare. Qualunque cosa sia, scommetto che richiederà un hack;)


2
Correggimi se sbaglio, ma non vedo nulla di sbagliato nella spiegazione per Boolean.ToString(). bool.TrueStringè un campo di sola lettura che contiene il letterale hardcoded "True" . Pertanto, dire che restituisce TrueStringequivale a dire che restituisce il letterale hardcod "True" memorizzato in esso, dato che restituire una stringa restituisce sempre il valore e non un riferimento.
Fernando Neira,

21
Il risultato osservabile è lo stesso. L'implementazione non lo è.
Vojislav Stojkovic,

1
La compilazione di C # non sostituirà Boolean.TrueString con "True" nei risultati compilati. Se effettivamente facessero uso di Boolean.TrueString, allora potresti usare la riflessione per cambiare Boolean.TrueString per restituire una versione minuscola ... ovviamente chissà cosa si sarebbe rotto. È comunque possibile utilizzare la riflessione per sostituire il metodo ToString su Boolean in modo che restituisca le varianti minuscole.
Dewey Vozel,

2
@FernandoNeira, se domani il valore letterale hardcoded TrueStringviene modificato, diciamo, in minuscolo "vero", il metodo bool.ToString()restituirà comunque il caso pasquale "Vero" letterale.
Serge,

1
Incolpo Visual Basic, che usa True e False come valori letterali.
mrcrowl,

105

... perché l'ambiente .NET è progettato per supportare molte lingue.

System.Boolean (in mscorlib.dll) è progettato per essere utilizzato internamente dalle lingue per supportare un tipo di dati booleano. C # usa tutte le lettere minuscole per le sue parole chiave, quindi "bool", "true" e "false".

VB.NET utilizza tuttavia il case standard: da qui 'Boolean', 'True' e 'False'.

Poiché le lingue devono lavorare insieme, non è possibile avere true.ToString () (C #) che dia un risultato diverso a True.ToString () (VB.NET). I progettisti di CLR hanno scelto la notazione di involucro CLR standard per il risultato ToString ().

La rappresentazione in formato stringa del valore booleano true è definita come Boolean.TrueString.

(C'è un caso simile con System.String: C # lo presenta come il tipo 'stringa').


4
Hanno dovuto accogliere VB dall'aspetto delle cose
Chris S

5
Direi che C # è il linguaggio "dispari". Tutto ciò che è pubblico in .NET è CamelCase - System.Boolean, True, System.String, ecc. - È l'eredità C di C # che porta all'aliasing di String to string, Boolean a boolean, True a true, ecc. (Anche se la mia preferenza personale è ancora C #).
stusmith,

4
Inoltre, la buona ragione (per me) sta convertendo in minuscolo è facile mentre è difficile renderlo CamelCase specialmente quando VB è usato proprio come ha detto @John Burns. Altrimenti l'utente VB non può e non utilizzerà mai il ToString()e ha costretto a usare like If(b, "True", "False"). Quindi un utente c # come me deve sacrificarsi per usare ToLower():)
CallMeLaNN l'

2
@MarkLopez Il tuo commento non è corretto, vedi qui: msdn.microsoft.com/en-us/library/c8f5xwh7.aspx . Inoltre, cercare la definizione booleana rivela che in realtà è una struttura e che i due hanno le stesse proprietà.
Tsemer,

1
Mentre la tua risposta fa luce, non capisco come "Vero" sia più "standard" che "vero". Sembra che quest'ultimo sia molto più popolare.
Leggero

50

Per Xml è possibile utilizzare il metodo XmlConvert.ToString .


4
Questo sembra di gran lunga il metodo più elegante. Nessuna programmazione aggiuntiva e l'utilizzo di una libreria ufficiale effettivamente creata ai fini dell'output xml.
Nyerguds,

25

È un semplice codice per convertirlo in minuscolo.

Tuttavia, non è così semplice convertire "vero" in "Vero".

true.ToString().ToLower() 

è quello che uso per l'output XML.


Oltre alla risposta di @stusmith perché supporta molte lingue, questo è un buon motivo per cui Microsoft preferisce l'aspetto VB del ToString()risultato booleano .
CallMeLaNN,

@Damieh: in realtà, la domanda è "Perché". La risposta selezionata, a differenza di questa, in realtà si avvicina il più possibile alla risposta.
Nyerguds,

1
Meglio ancora; ToLowerInvariant().
corvo vulcanico

3
È possibile utilizzare System.Globalization.CultureInfo.InvariantCulture.TextInfo.ToTitleCase per convertire "true" in "True".
Jenny O'Reilly,

8

In che modo non è compatibile con C #? Boolean.Parse e Boolean. TryParse non fanno distinzione tra maiuscole e minuscole e l'analisi viene eseguita confrontando il valore con Boolean.TrueString o Boolean.FalseString che sono "True" e "False".

EDIT: guardando il metodo Boolean.ToString nel riflettore si scopre che le stringhe sono hard coded, quindi il metodo ToString è il seguente:

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

23
Wow ... Questo è probabilmente l'unico contesto in C # in cui il costrutto "if (! This)" è valido!
Tamas Czinege,

2
quindi perché non è che restituire "falso" è quello che sto chiedendo
Chris S

Che cosa strana da fare ... intendo invertire la condizione.
nicodemus13

6
@TamasCzinege That's probably the only context in C# where the construct "if (!this)" is valid! Mi hai sfidato, perdi . gist.github.com/Steinblock/10df18afb948866be1ba - Anche oggi è il 200esimo compleanno di George Boole
Jürgen Steinblock,

Mi chiedo perché non è stato fatto come return this ? "True" : "False";? (Un altro caso insolito che non si vede spesso thiscome una ?:condizione, ma qui avrebbe senso.)
Darrel Hoffman,

7

Conosco il motivo per cui è già stato affrontato, ma quando si tratta di formattazione booleana "personalizzata", ho due metodi di estensione di cui non posso più vivere senza :-)

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

L'uso è banale. Quanto segue converte vari valori bool nelle loro rappresentazioni portoghesi:

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

"Puoi utilizzare i metodi di estensione per estendere una classe o un'interfaccia, ma non per sovrascriverli. Un metodo di estensione con lo stesso nome e la stessa firma di un metodo di interfaccia o classe non verrà mai chiamato. Al momento della compilazione, i metodi di estensione hanno sempre una priorità inferiore rispetto a metodi di istanza definiti nel tipo stesso. " La tua soluzione funziona? (Forse ToString () è ereditato, quindi può essere
annullato

1
Immagino che al mio precedente commento questa firma non prevalga su nulla.
jwize,

@jwize sì, queste sono nuove firme, quindi è un sovraccarico, non una sostituzione ;-)
Loudenvier

0

Il motivo trueè "True" a causa del forte legame di Microsoft con gli standard XML.

Da Wikipedia : "Extensible Markup Language (XML) è un linguaggio di markup che definisce un insieme di regole per la codifica dei documenti in un formato che è sia leggibile dall'uomo che leggibile dalla macchina".

Leggibile dall'uomo è soggettivo, ma agli occhi di XML, si preferisce usare la parola "Uno" al posto del numero "1". Noterai che ciò accade usando enum, poiché la parola viene serializzata invece del suo valore ("FirstOption" invece di "0" o "1").

Allo stesso modo, il testo segue comunemente CamelCasing . Pertanto, anziché "stringa", XML preferisce "stringa". Questo è il motivo per cui Boolean.TrueString è "True" e Boolean.FalseString è "False" per impostazione predefinita.


7
Divertente che il booleano XML si interrompa se lo imposti su "Vero" e non "vero" allora? - "Nota che XML fa distinzione tra maiuscole e minuscole e che la specifica XML riconosce" vero "e" falso "come l'insieme valido di valori booleani"
PandaWood,

-1

Ciò probabilmente risale ai vecchi giorni VB NOT .Net quando bool.ToString produceva True o False.


3
Prima di .NET il tipo di dati booleani in VB (in effetti, tutti i tipi di dati) non aveva metodi.
Sam Axe

1
In VB6, puoi ancora convertire il tipo booleano in stringa (il modo più semplice per assegnarlo a una variabile String). La cosa strana di questo, era che la conversione era in realtà specifica per la cultura, quindi se il tuo linguaggio di cultura sul computer in esecuzione era norvegese, il risultato era "Sann" e "Usann" invece di "Vero" e "Falso"! Ciò spesso causava problemi se le impostazioni booleane venivano archiviate in un file di testo ed esportate in un ambiente diverso in cui il computer era configurato con la cultura inglese (USA).
timore del
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.