Mengapa Boolean.ToString menampilkan "Benar" dan bukan "benar"

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

Output:
True
False

Apakah ada alasan yang sah untuk itu menjadi "Benar" dan bukan "benar"? Itu rusak ketika menulis XML sebagai tipe boolean XML adalah huruf kecil , dan juga tidak kompatibel dengan C # benar / salah (meskipun tidak yakin tentang CLS).

Memperbarui

Ini adalah cara saya yang sangat rumit untuk menyiasatinya dalam C # (untuk digunakan dengan XML)

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

Tentu saja itu menambahkan 1 metode lagi ke stack, tetapi menghilangkan ToLowers () di mana-mana.

Chris S
sumber
1
Hanya berpikir saya akan menyebutkan ini ... Saya baru saja membaca beberapa solusi cerdas untuk deserialize "Benar" sebagai tipe boolean dalam C # di blog msdn! lihat http://blogs.msdn.com/helloworld/archive/2009/04/03/workaround-to-deserialize-true-false-using-xmlserializer.aspx
Peter
23
Saya akan ganti return b.ToString().ToLower();dengan return b ? "true" : "false";. Lebih bersih, lebih efisien, kurang tergantung pada metode yang secara teoritis dapat bergantung pada lokal (meskipun tidak dalam implementasi saat ini).
Jon Hanna
1
Ini juga cukup menjengkelkan ketika menggunakan RestSharp untuk membuat serial properti publik dari suatu objek menjadi QueryString untuk membuat panggilan REST WebService. Jika REST API peka huruf besar-kecil untuk bools (mis. Google Directions API) maka ini menyebabkan panggilan API gagal.
Carlos P
8
"ToString adalah metode pemformatan utama dalam .NET Framework. Ia mengonversi objek ke representasi string sehingga cocok untuk ditampilkan ." (Menekankan milikku). Object.ToString bukan mekanisme serialisasi . :)
Rytmis
1
@ ya, itulah pengalaman yang membuat saya berjaga-jaga terhadap risiko teoretis meskipun saat ini tidak terjadi.
Jon Hanna

Jawaban:

165

Hanya orang-orang dari Microsoft yang dapat menjawab pertanyaan itu. Namun, saya ingin menawarkan beberapa fakta menyenangkan tentang hal itu;)

Pertama, ini adalah apa yang dikatakan di MSDN tentang metode Boolean.ToString () :

Nilai Pengembalian

Jenis: Sistem. Tali

TrueString jika nilai instance ini benar, atau FalseString jika nilai instance ini salah.

Catatan

Metode ini mengembalikan konstanta "Benar" atau "Salah". Perhatikan bahwa XML peka huruf besar kecil, dan bahwa spesifikasi XML mengakui "benar" dan "salah" sebagai set nilai Boolean yang valid. Jika objek String yang dikembalikan oleh metode ToString () harus ditulis ke file XML, metode String.ToLower harus dipanggil terlebih dahulu untuk mengubahnya menjadi huruf kecil.

Inilah fakta menyenangkan # 1: itu tidak mengembalikan TrueString atau FalseString sama sekali. Ini menggunakan hardcoded literals "True" dan "False". Tidak akan ada gunanya bagimu jika menggunakan bidang, karena mereka ditandai sebagai hanya baca, jadi tidak ada perubahan.

Metode alternatif, Boolean.ToString (IFormatProvider) bahkan lebih lucu:

Catatan

Parameter penyedia dicadangkan. Itu tidak berpartisipasi dalam pelaksanaan metode ini. Ini berarti bahwa metode Boolean.ToString (IFormatProvider), tidak seperti kebanyakan metode dengan parameter penyedia, tidak mencerminkan pengaturan khusus budaya.

Apa solusinya? Tergantung pada apa yang sebenarnya Anda coba lakukan. Apa pun itu, saya yakin itu akan membutuhkan hack;)

Vojislav Stojkovic
sumber
2
Koreksi saya jika saya salah, tetapi saya tidak melihat ada yang salah dengan penjelasannya Boolean.ToString(). bool.TrueStringadalah bidang baca-saja yang berisi literal hardcoded "True" . Oleh karena itu, mengatakan bahwa ia mengembalikan TrueStringadalah sama dengan mengatakan itu mengembalikan hardcoded literal "True" yang tersimpan di dalamnya, mengingat bahwa mengembalikan string selalu mengembalikan nilai dan bukan referensi.
Fernando Neira
21
Hasil yang dapat diamati adalah sama. Implementasinya tidak.
Vojislav Stojkovic
1
Kompilasi C # tidak akan menggantikan Boolean.TrueString dengan "True" di hasil kompilasi. Jika mereka benar-benar memanfaatkan Boolean. TrueString maka Anda dapat menggunakan refleksi untuk mengubah Boolean. TrueString untuk mengembalikan versi huruf kecil ... tentu saja siapa yang tahu apa yang akan merusak. Anda masih bisa menggunakan refleksi untuk mengganti metode ToString pada Boolean sehingga mengembalikan varian huruf kecil.
Dewey Vozel
2
@FernandoNeira, jika besok hardcoded literal TrueStringdiubah, katakanlah, menjadi huruf kecil "true", metode bool.ToString()ini masih akan mengembalikan case pascal "True" literal.
Serge
1
Saya menyalahkan Visual Basic, yang menggunakan Benar dan Salah sebagai nilai literalnya.
mrcrowl
105

... karena lingkungan .NET dirancang untuk mendukung banyak bahasa.

System.Boolean (dalam mscorlib.dll) dirancang untuk digunakan secara internal oleh bahasa untuk mendukung tipe data boolean. C # menggunakan semua huruf kecil untuk kata kunci, karenanya 'bool', 'true', dan 'false'.

Namun VB.NET menggunakan casing standar: karenanya 'Boolean', 'True', dan 'False'.

Karena bahasa harus bekerja bersama, Anda tidak bisa memiliki true.ToString () (C #) memberikan hasil yang berbeda untuk True.ToString () (VB.NET). Desainer CLR memilih notasi casing CLR standar untuk hasil ToString ().

Representasi string dari true boolean didefinisikan sebagai Boolean.TrueString.

(Ada kasus serupa dengan System.String: C # menyajikannya sebagai tipe 'string').

tukang kayu
sumber
4
Mereka harus mengakomodasi VB dari penampilan
Chris S
5
Saya akan mengatakan C # adalah bahasa "aneh". Segala sesuatu yang publik di .NET adalah CamelCase - System.Boolean, True, System.String, dll - itu adalah warisan C # yang mengarah pada aliasing dari String ke string, Boolean ke bool, Teguh ke benar, dll. (Meskipun preferensi pribadi saya adalah masih C #).
stusmith
4
Selain itu, alasan yang bagus (bagi saya) adalah mengkonversi ke huruf kecil adalah mudah sementara sulit untuk membuatnya CamelCase terutama ketika VB digunakan seperti yang dikatakan @John Burns. Kalau tidak, pengguna VB tidak bisa dan tidak akan pernah menggunakan ToString()dan mereka dipaksa untuk menggunakan suka If(b, "True", "False"). Jadi c # pengguna seperti saya harus berkorban untuk menggunakan ToLower():)
CallMeLaNN
2
@MarkLopez Komentar Anda salah, lihat di sini: msdn.microsoft.com/en-us/library/c8f5xwh7.aspx . Juga, mencari definisi Boolean mengungkapkan itu sebenarnya sebuah struct, dan keduanya memiliki sifat yang sama.
tsemer
1
Sementara jawaban Anda memberi sedikit penjelasan, saya tidak mengerti bagaimana "Benar" lebih "standar" daripada "benar". Sepertinya yang terakhir jauh lebih populer.
Sedikit
50

Untuk Xml Anda dapat menggunakan metode XmlConvert.ToString .

bruno conde
sumber
4
Sejauh ini metode yang paling elegan. Tidak ada pemrograman tambahan, dan menggunakan perpustakaan resmi sebenarnya dibuat untuk tujuan output xml.
Nyerguds
25

Ini kode sederhana untuk mengonversi itu menjadi huruf kecil semua.

Namun, tidak sesederhana itu untuk mengubah "benar" menjadi "Benar".

true.ToString().ToLower() 

adalah apa yang saya gunakan untuk output xml.

John
sumber
Selain jawaban @stusmith karena mendukung banyak bahasa, ini alasan bagus mengapa Microsoft lebih menyukai tampilan VB dari ToString()hasil boolean .
CallMeLaNN
@Damieh: sebenarnya, pertanyaannya adalah "Kenapa". Jawaban yang dipilih, tidak seperti ini, sebenarnya sedekat mungkin dengan menjawabnya.
Nyerguds
1
Lebih baik; ToLowerInvariant().
gagak vulcan
3
Anda dapat menggunakan System.Globalization.CultureInfo.InvariantCulture.TextInfo.ToTitleCase untuk mengonversi "true" kembali ke "True".
Jenny O'Reilly
8

Bagaimana itu tidak kompatibel dengan C #? Boolean.Parse dan Boolean.TryParse adalah case-sensitive dan parsing dilakukan dengan membandingkan nilainya dengan Boolean.TrueString atau Boolean.FalseString yang "Benar" dan "Salah".

EDIT: Ketika melihat metode Boolean.ToString di reflektor ternyata string dikodekan sehingga metode ToString adalah sebagai berikut:

public override string ToString()
{
    if (!this)
    {
        return "False";
    }
    return "True";
}
Rune Grimstad
sumber
23
Wow ... Itu mungkin satu-satunya konteks di C # di mana konstruk "jika (! Ini)" valid!
Tamas Czinege
2
jadi mengapa tidak mengembalikan "false" adalah apa yang saya tanyakan
Chris S
Suatu hal yang aneh untuk dilakukan ... Maksudku membalikkan kondisinya.
nicodemus13
6
@TamasCzinege That's probably the only context in C# where the construct "if (!this)" is valid! Anda menantangku, Anda longgar. gist.github.com/Steinblock/10df18afb948866be1ba - Juga hari ini adalah hari jadi ke-200 dari George Boole
Jürgen Steinblock
Bertanya-tanya mengapa ini tidak dilakukan return this ? "True" : "False";? (Kasus lain yang tidak biasa karena Anda tidak sering melihat thissebagai suatu ?:kondisi, tetapi di sini masuk akal.)
Darrel Hoffman
7

Saya tahu alasan mengapa cara ini telah ditangani, tetapi ketika datang ke format "custom" boolean, saya punya dua metode ekstensi yang saya tidak bisa hidup tanpanya :-)

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

Penggunaan itu sepele. Berikut ini mengkonversi berbagai nilai bool ke representasi Portugis mereka:

string verdadeiro = true.ToString("verdadeiro", "falso");
string falso = false.ToString("verdadeiro", "falso");
bool? v = null;
string nulo = v.ToString("verdadeiro", "falso", "nulo");
Loudenvier
sumber
"Anda dapat menggunakan metode ekstensi untuk memperluas kelas atau antarmuka, tetapi tidak untuk menimpanya. Metode ekstensi dengan nama dan tanda tangan yang sama dengan metode antarmuka atau kelas tidak akan pernah dipanggil. Pada waktu kompilasi, metode ekstensi selalu memiliki prioritas lebih rendah daripada metode instan didefinisikan dalam tipe itu sendiri. " Apakah solusi Anda berfungsi? (Mungkin ToString () diwarisi karenanya dapat diganti?)
jwize
1
Saya kira komentar saya sebelumnya tanda tangan ini tidak mengesampingkan apa pun.
jwize
@ Jwize ya, ini adalah tanda tangan baru, jadi itu adalah overload bukan override ;-)
Loudenvier
0

Alasannya true adalah "Benar" adalah karena ikatan kuat Microsoft dengan standar XML.

Dari Wikipedia : "Extensible Markup Language (XML) adalah bahasa markup yang mendefinisikan seperangkat aturan untuk menyandikan dokumen dalam format yang dapat dibaca oleh manusia. dan bisa mesin."

Dapat dibaca manusia bersifat subyektif, tetapi di mata XML, menggunakan kata "One" sebagai ganti angka "1" lebih disukai. Anda akan melihat ini terjadi menggunakan enum, karena kata tersebut menjadi bersambung bukan dari nilainya ("FirstOption", bukan "0" atau "1").

Demikian juga, teks biasanya mengikuti CamelCasing . Oleh karena itu, alih-alih "string", XML lebih suka "String". Inilah sebabnya mengapa Boolean.TrueString adalah "True" dan Boolean.FalseString adalah "False" secara default.

Kody
sumber
7
Lucu bahwa XML boolean akan rusak jika Anda mengaturnya ke "True" dan bukan "true"? - "Perhatikan bahwa XML peka terhadap huruf besar-kecil, dan bahwa spesifikasi XML mengakui" benar "dan" salah "sebagai set nilai Boolean yang valid"
PandaWood
-1

Ini mungkin berasal dari VB lama TIDAK. Net hari ketika bool.ToString menghasilkan Benar atau Salah.

cjk
sumber
3
Sebelum .NET tipe data Boolean di VB (pada kenyataannya, semua tipe data) tidak memiliki metode.
Sam Axe
1
Di VB6, Anda masih bisa mengonversi tipe Boolean ke string (cara paling sederhana untuk menetapkannya ke variabel String). Yang aneh tentang ini, adalah bahwa konversi itu sebenarnya spesifik budaya, jadi jika bahasa budaya Anda di komputer yang menjalankan adalah Norwegia, hasilnya adalah "Sann" dan "Usann" bukannya "Benar" dan "Salah"! Ini sering menimbulkan masalah jika pengaturan boolean disimpan dalam file teks, dan diekspor ke lingkungan yang berbeda di mana komputer diatur dengan budaya bahasa Inggris (AS).
awe