Чому Boolean.ToString виводить "True", а не "true"


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

Output:
True
False

Чи є поважна причина того, що вона є "Правда", а не "правда"? Він порушується при написанні XML, оскільки булевий тип XML є малим регістром , а також не сумісний з істинним / хибним C # (хоч невідомо про CLS).

Оновлення

Ось мій дуже хакітний спосіб обійти його в C # (для використання з XML)

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

Звичайно, це додає ще 1 метод до стеку, але видаляє ToLowers () скрізь.


1
Просто подумав, що я згадаю це ... Я щойно прочитав кілька розумних способів десеріалізації "True" як булівського типу в C # на блозі msdn! дивіться http://blogs.msdn.com/helloworld/archive/2009/04/03/workaround-to-deserialize-true-false-using-xmlserializer.aspx
Пітер

23
Я замінив би return b.ToString().ToLower();на return b ? "true" : "false";. Чистіший, більш ефективний, менш залежний від методу, який теоретично міг би залежати від локальної точки зору (навіть якщо цього немає в поточних реалізаціях).
Джон Ханна

1
Це також дуже дратує, коли використовується RestSharp для серіалізації загальнодоступних властивостей об'єкта в QueryString для здійснення виклику REST WebService. Якщо API REST чутливий до регістру для булів (наприклад, API Google Directions), це призводить до відмови виклику API.
Карлос П

8
"ToString - це основний метод форматування в .NET Framework. Він перетворює об'єкт у його рядкове представлення, щоб він був придатним для відображення ." (Наголос мій). Object.ToString не є механізмом серіалізації . :)
Ритміс

1
@ Так, це такий досвід, який приводить мене до захисту від теоретичного ризику, хоча цього в даний час не відбувається.
Джон Ханна

Відповіді:


165

Тільки люди з Microsoft дійсно можуть відповісти на це питання. Однак я хотів би запропонувати цікаві факти про це;)

По-перше, це те, що йдеться в MSDN про метод Boolean.ToString () :

Повернене значення

Тип: System.String

TrueString, якщо значення цього примірника є істинним, або FalseString, якщо значення цього екземпляра помилкове.

Зауваження

Цей метод повертає константи "True" або "False". Зауважте, що XML відрізняється від регістру, а специфікація XML визнає "true" та "false" як дійсний набір булевих значень. Якщо об'єкт String, повернутий методом ToString (), повинен бути записаний у XML-файл, його спочатку слід викликати метод String.ToLower, щоб перетворити його в малі регістри.

Ось прийшов цікавий факт №1: він взагалі не повертає TrueString або FalseString. Він використовує твердо кодовані літерали "True" та "False". Не принесе вам нічого корисного, якби вони використовували поля, оскільки вони позначені як прочитані тільки тому, так що їх не змінюється.

Альтернативний метод, Boolean.ToString (IFormatProvider) , ще смішніший:

Зауваження

Параметр провайдера зарезервований. Він не бере участі у виконанні цього методу. Це означає, що метод Boolean.ToString (IFormatProvider), на відміну від більшості методів з параметром постачальника, не відображає специфічних для культури параметрів.

Яке рішення? Залежить від того, що саме ви намагаєтеся зробити. Як би там не було, я думаю, що це вимагатиме злому;)


2
Виправте мене, якщо я помиляюся, але я не бачу нічого поганого в поясненні Boolean.ToString(). bool.TrueString- це поле лише для читання, яке містить твердо кодований літерал "True" . Отже, сказати, що він повертається TrueString- це те саме, що сказати, що він повертає твердо кодований літерал "True", збережений у ньому, враховуючи, що повернення рядка завжди повертає значення, а не посилання.
Фернандо Нейра

21
Результат, що спостерігається, той самий. Реалізація - ні.
Воєслав Стойкович

1
Компіляція C # не замінить Boolean.TrueString на "True" у зібраних результатах. Якщо вони насправді скористалися Boolean.TrueString, ви можете використати відображення, щоб змінити Boolean.TrueString, щоб повернути малу версію ... звичайно, хто знає, що це зламає. Ви все ще можете використовувати відображення для заміни методу ToString на Boolean, щоб він повертав нижній регістр варіантів.
Дьюї Возел

2
@FernandoNeira, якщо завтра літературний код із твердим кодом TrueStringбуде змінений, скажімо, на малий регістр "true", метод bool.ToString()все одно поверне паскальний регістр "True" в буквальний.
Серж

1
Я звинувачую Visual Basic, який використовує True та False в якості своїх буквальних значень.
mrcrowl

105

... оскільки середовище .NET призначене для підтримки багатьох мов.

System.Boolean (в mscorlib.dll) призначений для внутрішнього використання мовами для підтримки булевого типу даних. C # використовує всі малі літери для своїх ключових слів, отже, "bool", "true" та "false".

Однак VB.NET використовує стандартний кожух: отже, "Boolean", "True" та "False".

Оскільки мови повинні працювати разом, ви не могли мати true.ToString () (C #), що дасть інший результат True.ToString () (VB.NET). Дизайнери CLR вибрали стандартні позначення корпусу CLR для результату ToString ().

Представлення рядків boolean true визначається як Boolean.TrueString.

(Є схожий випадок із System.String: C # представляє його як тип 'string').


4
Вони повинні були вмістити VB з вигляду речей
Chris S

5
Я б сказав, що C # є "дивною" мовою. Все, що відкрито в .NET, - це CamelCase - System.Boolean, True, System.String тощо. Це спадщина C #, що призводить до згладжування String для string, Boolean to bool, True to true тощо. (Хоча мої особисті переваги: ще C #).
стусміт

4
Крім того, хороша причина (для мене) - перетворення на малі регістри - це просто, хоча важко зробити це CamelCase, особливо коли VB використовується так, як сказав @John Burns. В іншому випадку користувач VB не може і ніколи не використовуватиме, ToString()і вони змушені користуватися подібним чином If(b, "True", "False"). Тож c # користувачеві, як я, потрібно пожертвувати, щоб використовувати ToLower():)
CallMeLaNN

2
@MarkLopez Ваш коментар невірний, дивіться тут: msdn.microsoft.com/en-us/library/c8f5xwh7.aspx . Крім того, пошук булевого визначення виявляє, що насправді це структура, і вони мають однакові властивості.
цемер

1
Хоча ваша відповідь проливає трохи світла, я не розумію, наскільки "True" є "стандартніше", ніж "true". Здається, останній набагато популярніший.
Невеликий

50

Для Xml ви можете використовувати метод XmlConvert.ToString .


4
Це здається найвишуканішим методом. Без додаткового програмування та використання офіційної бібліотеки, фактично створеної для виведення xml.
Nyerguds

25

Простий код перетворити його на всі малі регістри.

Однак не так просто перетворити "справжнє" на "Істинне".

true.ToString().ToLower() 

це те, що я використовую для виводу xml.


На додаток до відповіді @stusmith, оскільки підтримка багатьох мов, це приємна причина, чому Microsoft вважає за краще VB вигляд булевого ToString()результату.
CallMeLaNN

@Damieh: власне, питання "Чому". Обрана відповідь, на відміну від цього, насправді наближається до відповіді на те, наскільки це можливо.
Nyerguds

1
Ще краще; ToLowerInvariant().
вулкан ворон

3
Ви можете використовувати System.Globalization.CultureInfo.InvariantCulture.TextInfo.ToTitleCase для перетворення "true" назад у "True".
Дженні О'Рейлі

8

Як це не сумісно з C #? Boolean.Parse і Boolean.TryParse є нечутливим до регістру, і аналіз проводиться шляхом порівняння значення з Boolean.TrueString або Boolean.FalseString, які є "True" і "False".

EDIT: При перегляді методу Boolean.ToString у відбивачі виявляється, що рядки жорстко закодовані, тому метод ToString виглядає наступним чином:

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

23
Нічого ... Це, мабуть, єдиний контекст у C #, де конструкція "if (! This)" є дійсною!
Тамас Цінеге

2
так чому я не повертаюсь "помилково" - це те, про що я питаю
Chris S

Що дивного робити ... я маю на увазі перевернути умову.
nicodemus13

6
@TamasCzinege That's probably the only context in C# where the construct "if (!this)" is valid! Ти кинув мені виклик, ти розпущений. gist.github.com/Steinblock/10df18afb948866be1ba - Також сьогодні 200-та річниця Джорджа Була
Юрген Штейнблок

Цікаво, чому це не було зроблено так return this ? "True" : "False";? (Ще один незвичайний випадок, який ви часто не сприймаєте thisяк ?:умову, але тут це має сенс.)
Даррель Гофман

7

Я знаю причину, по якій це вже було вирішено, але коли мова йде про "користувацьке" булеве форматування, у мене є два способи розширення, без яких я вже не можу жити :-)

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

Використання тривіальне. Нижче перетворюються різні значення bool у їхні португальські подання:

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

"Ви можете використовувати методи розширення для розширення класу або інтерфейсу, але не для їх заміни. Спосіб розширення з тим самим іменем та підписом, як інтерфейс або метод класу, ніколи не буде викликаний. У час компіляції методи розширення завжди мають нижчий пріоритет, ніж методи екземпляра, визначені в самому типі. " Чи працює ваше рішення? (Можливо, ToString () успадковується, тому його можна змінити?)
jwize

1
Я думаю, що на мій попередній коментар цей підпис нічого не перекреслює.
jwize

@jwize так, це нові підписи, тож це перевантаження, а не переоцінка ;-)
Loudenvier

0

Причина true"True" - це міцна зв'язок Microsoft зі стандартами XML.

З Вікіпедії : "Розширювана мова розмітки (XML) - мова розмітки, яка визначає набір правил для кодування документів у форматі, який читається людиною і читається машиною".

Людина, що читається, є суб'єктивною, але в очах XML кращим є використання слова "Один" замість числа "1". Ви помітите, що це відбувається за допомогою enums, оскільки слово отримує серіалізацію замість свого значення ("FirstOption" замість "0" або "1").

Аналогічно, текст зазвичай слід CamelCasing . Тому замість "string" XML віддає перевагу "String". Ось чому Boolean.TrueString є "True", а Boolean.FalseString - "False" за замовчуванням.


7
Смішно, що XML-булева система зламається, якщо встановити її на "True", а не "true"? - "Зауважте, що XML відрізняється від регістру, і те, що специфікація XML визнає" true "та" false "як дійсний набір булевих значень"
PandaWood

-1

Це, ймовірно, шкодить від старого VB NOT .Net днів, коли bool.ToString створив True або False.


3
До .NET типу булевих даних у VB (фактично, всі типи даних) не було методів.
Сем Акс

1
У VB6 ви все ще можете перетворити тип Boolean у рядок (найпростіший спосіб призначити його змінної String). Дивним у цьому було те, що перетворення насправді було специфічним для культури, тому якщо ваша культурна мова на працюючому комп’ютері була норвезькою, результатом стали "Sann" та "Usann" замість "True" та "False"! Це часто спричиняло проблеми, якщо булеві параметри зберігалися в текстовому файлі та експортувалися в інше середовище, де комп'ютер був налаштований з англійською (американською) культурою.
трепет
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.