ทำไมบูลีนถึงเอาท์พุท“ จริง” และไม่“ จริง”


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
แค่คิดว่าฉันพูดถึงเรื่องนี้ ... ฉันเพิ่งอ่านวิธีแก้ปัญหาที่ชาญฉลาดเพื่อ deserialize "True" เป็นประเภทบูลีนใน C # ในบล็อก msdn! ดูhttp://blogs.msdn.com/helloworld/archive/2009/04/03/workaround-to-deserialize-true-false-using-xmlserializer.aspx
Peter

23
ฉันต้องการแทนที่ด้วยreturn b.ToString().ToLower(); return b ? "true" : "false";สะอาดขึ้นมีประสิทธิภาพมากขึ้นขึ้นอยู่กับวิธีการทางทฤษฎีที่อาจขึ้นอยู่กับตำแหน่งที่ตั้ง (แม้ว่าจะไม่ได้ใช้งานในปัจจุบัน)
Jon Hanna

1
สิ่งนี้ยังค่อนข้างน่ารำคาญเมื่อใช้ RestSharp เพื่อทำให้คุณสมบัติสาธารณะของวัตถุเป็น QueryString เพื่อทำการเรียกใช้บริการเว็บ REST หาก REST API เป็นตัวพิมพ์เล็กและตัวพิมพ์ใหญ่สำหรับ bools (เช่น Google Directions API) นี่จะทำให้การเรียก API ล้มเหลว
Carlos P

8
"ToString เป็นวิธีการจัดรูปแบบที่สำคัญใน. NET Framework ซึ่งจะแปลงวัตถุเป็นการแสดงสตริงเพื่อให้เหมาะสำหรับแสดง " (เน้นเหมือง) Object.ToString ไม่ใช่กลไกการทำให้เป็นอนุกรม :)
Rytmis

1
@ ใช่ใช่นั่นเป็นประสบการณ์ที่ทำให้ฉันต้องระวังความเสี่ยงทางทฤษฎีแม้ว่ามันจะไม่เกิดขึ้นในขณะนี้
Jon Hanna

คำตอบ:


165

มีเพียงคนจาก Microsoft เท่านั้นที่สามารถตอบคำถามนี้ได้ อย่างไรก็ตามฉันต้องการนำเสนอข้อเท็จจริงสนุก ๆ เกี่ยวกับมัน)

อันดับแรกนี่คือสิ่งที่กล่าวใน MSDN เกี่ยวกับวิธีBoolean.ToString () :

ส่งคืนค่า

ประเภท: System.String

TrueStringถ้าค่าของอินสแตนซ์นี้เป็นจริงหรือFalseStringถ้าค่าของอินสแตนซ์นี้เป็นเท็จ

หมายเหตุ

วิธีนี้จะส่งคืนค่าคงที่ "True" หรือ "False" โปรดทราบว่า XML เป็นแบบตรงตามตัวพิมพ์ใหญ่ - เล็กและข้อมูลจำเพาะ XML รู้จัก "true" และ "false" เป็นชุดค่าบูลีนที่ถูกต้อง หากวัตถุ String ที่ส่งคืนโดย ToString () วิธีการจะถูกเขียนไปยังไฟล์ XML, วิธีการ String.ToLower ของมันควรจะเรียกว่าก่อนเพื่อแปลงเป็นตัวพิมพ์เล็ก

นี่คือข้อเท็จจริงที่สนุก # 1: มันจะไม่ส่งคืน TrueString หรือ FalseString เลย มันใช้ตัวอักษรฮาร์ดคอร์ "จริง" และ "เท็จ" จะไม่ทำอะไรให้คุณดีเลยถ้ามันใช้ฟิลด์เพราะมันถูกทำเครื่องหมายว่าอ่านได้อย่างเดียวดังนั้นจึงไม่มีการเปลี่ยนแปลง

วิธีทางเลือกBoolean.ToString (IFormatProvider)นั้นสนุกกว่า:

หมายเหตุ

พารามิเตอร์ตัวให้บริการถูกสงวนไว้ มันไม่ได้มีส่วนร่วมในการดำเนินการของวิธีนี้ ซึ่งหมายความว่าเมธอด Boolean.ToString (IFormatProvider) ซึ่งแตกต่างจากวิธีส่วนใหญ่ที่มีพารามิเตอร์ตัวให้บริการไม่ได้สะท้อนถึงการตั้งค่าเฉพาะวัฒนธรรม

ทางออกคืออะไร? ขึ้นอยู่กับสิ่งที่คุณพยายามจะทำ ไม่ว่ามันจะเป็นอะไรฉันพนันได้เลยว่ามันจะต้องแฮก)


2
ถูกต้องฉันหากฉันผิด Boolean.ToString()แต่ฉันไม่เห็นผิดอะไรกับคำอธิบายสำหรับ bool.TrueStringเป็นเขตที่อ่านอย่างเดียวที่มีฮาร์ดโค้ดตัวอักษร"ทรู" ดังนั้นการบอกว่ามันจะส่งกลับTrueStringเป็นเหมือนการบอกว่ามันจะคืนค่าตัวอักษร hardcoded "True" ที่เก็บไว้ในนั้นเนื่องจากการคืนค่าสตริงจะส่งคืนค่าเสมอไม่ใช่การอ้างอิง
Fernando Neira

21
ผลลัพธ์ที่สังเกตได้เหมือนกัน การใช้งานไม่ได้
Vojislav Stojkovic

1
การคอมไพล์ C # จะไม่แทนที่ Boolean.TrueString ด้วย "True" ในผลลัพธ์ที่คอมไพล์แล้ว หากพวกเขาใช้ประโยชน์จาก Boolean.TrueString จริงๆแล้วคุณสามารถใช้การไตร่ตรองเพื่อเปลี่ยน Boolean.TrueString เพื่อส่งคืนเวอร์ชันตัวพิมพ์เล็ก ... แน่นอนว่าใครจะรู้ว่าอะไรจะแตก คุณยังสามารถใช้การสะท้อนเพื่อแทนที่เมธอด ToString ในบูลีนเพื่อให้ส่งคืนชุดตัวพิมพ์เล็กได้
Dewey Vozel

2
@FernandoNeira ถ้าพรุ่งนี้ตัวอักษร hardcoded TrueStringเปลี่ยนไปพูดให้เล็กลง "จริง" วิธีการbool.ToString()จะยังคงกลับกรณีปาสกาล "จริง" ตามตัวอักษร
Serge

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 ()

การแทนค่าสตริงของบูลีน true ถูกกำหนดให้เป็น Boolean.TrueString

(มีกรณีที่คล้ายกันกับ System.String: C # แสดงเป็นประเภท 'สตริง')


4
พวกเขาต้องรองรับ VB จากรูปลักษณ์ของสิ่งต่าง ๆ
Chris S

5
ฉันจะบอกว่า C # เป็นภาษา "แปลก" ทุกสิ่งทุกอย่างที่เป็นสาธารณะใน. NET คือ CamelCase - System.Boolean, True, System.String ฯลฯ - เป็นมรดกของ C # ซึ่งนำไปสู่นามแฝงของ String to string, Boolean to bool, True to true, ฯลฯ (ถึงแม้ว่าความชอบส่วนตัวของฉันคือ ยัง C #)
stusmith

4
นอกจากนี้เหตุผลที่ดี (สำหรับฉัน) การแปลงเป็นตัวพิมพ์เล็กนั้นเป็นเรื่องง่ายในขณะที่มันยากที่จะทำให้มันเป็น CamelCase โดยเฉพาะอย่างยิ่งเมื่อใช้ VB เช่นเดียวกับ @John Burns กล่าว มิฉะนั้นผู้ใช้ VB จะไม่สามารถและจะไม่ใช้ToString()และจะบังคับให้ใช้เช่นIf(b, "True", "False")นั้น ดังนั้นผู้ใช้ c # อย่างฉันต้องเสียสละเพื่อใช้ToLower():)
CallMeLaNN

2
@MarkLopez ความคิดเห็นของคุณไม่ถูกต้องดูที่นี่: msdn.microsoft.com/en-us/library/c8f5xwh7.aspx นอกจากนี้การค้นหาคำนิยามบูลีนแสดงให้เห็นว่าในความเป็นจริงแล้ว struct และทั้งสองมีคุณสมบัติเหมือนกัน
tsemer

1
ในขณะที่คำตอบของคุณให้แสงสว่างบางอย่างฉันไม่เข้าใจว่า "จริง" เป็น "มาตรฐาน" มากกว่า "จริง" ดูเหมือนว่าหลังเป็นที่นิยมมากขึ้น
เบี่ยง

50

สำหรับ Xml คุณสามารถใช้วิธีXmlConvert.ToString


4
นี่ดูเหมือนจะเป็นวิธีที่หรูหราที่สุด ไม่มีการเขียนโปรแกรมเพิ่มเติมและการใช้ห้องสมุดอย่างเป็นทางการสร้างขึ้นจริงเพื่อวัตถุประสงค์ในการส่งออก XML
Nyerguds

25

มันง่ายในการแปลงรหัสให้เป็นตัวพิมพ์เล็กทั้งหมด

ไม่ใช่เรื่องง่ายที่จะแปลง "จริง" กลับไปเป็น "จริง"

true.ToString().ToLower() 

คือสิ่งที่ฉันใช้สำหรับเอาต์พุต xml


นอกจากนี้คำตอบ @stusmith เพราะการสนับสนุนหลายภาษานี่คือเหตุผลว่าทำไมดีไมโครซอฟท์ต้องการดู VB ของบูลToString()ผล
CallMeLaNN

@Damieh: จริง ๆ แล้วคำถามคือ "ทำไม" คำตอบที่เลือกซึ่งแตกต่างจากนี้จริง ๆ แล้วใกล้เคียงกับการตอบรับมากที่สุด
Nyerguds

1
ดีกว่า; ToLowerInvariant().
Raven vulcan

3
คุณสามารถใช้ System.Globalization.CultureInfo.InvariantCulture.TextInfo.ToTitleCase เพื่อแปลง "true" กลับไปเป็น "True"
Jenny O'Reilly

8

มันเข้ากันไม่ได้กับ C # อย่างไร Boolean.Parse และ Boolean.TryParse เป็นตัวพิมพ์เล็กและตัวแยกวิเคราะห์โดยการเปรียบเทียบค่ากับ Boolean.TrueString หรือ Boolean.FalseString ซึ่งเป็น "True" และ "False"

แก้ไข: เมื่อดูที่วิธี Boolean.ToString ในตัวสะท้อนกลับกลายเป็นว่าสตริงที่มีการเข้ารหัสอย่างหนักดังนั้นวิธี ToString เป็นดังนี้:

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

23
ว้าว ... นั่นอาจเป็นบริบทเดียวใน C # ที่โครงสร้าง "if (! this)" นั้นถูกต้อง!
Tamas Czinege

2
ดังนั้นทำไมไม่ได้กลับ "เท็จ" คือสิ่งที่ฉันขอ
คริส 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 ปีของ George Boole
Jürgen Steinblock

สงสัยว่าทำไมนี้ไม่ได้ทำตามreturn this ? "True" : "False";? (อีกกรณีที่ผิดปกติในขณะที่คุณไม่ได้มองthisว่าเป็น?:เงื่อนไข แต่ที่นี่มันจะสมเหตุสมผล)
Darrel Hoffman

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

การใช้งานเป็นเรื่องเล็กน้อย ต่อไปนี้จะแปลงค่าบูลต่าง ๆ เป็นการนำเสนอแบบโปรตุเกส:

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 ใช่สิ่งเหล่านี้เป็นลายเซ็นใหม่ดังนั้นจึงไม่ใช่ override แทนที่ ;-)
Loudenvier

0

เหตุผลtrueก็คือ "True" เป็นเพราะความผูกพันที่แน่นแฟ้นของ Microsoft กับมาตรฐาน XML

จากวิกิพีเดีย : "Extensible Markup Language (XML) เป็นภาษามาร์กอัปที่กำหนดชุดของกฎสำหรับการเข้ารหัสเอกสารในรูปแบบที่ทั้งมนุษย์สามารถอ่านได้และเครื่องอ่านได้"

มนุษย์สามารถอ่านได้เป็นอัตนัย แต่ในสายตาของ XML การใช้คำว่า "หนึ่ง" แทนตัวเลข "1" เป็นสิ่งที่ต้องการ คุณจะสังเกตเห็นว่าสิ่งนี้เกิดขึ้นโดยใช้ enums เนื่องจากคำได้รับการทำให้เป็นอนุกรมแทนค่าของมัน ("FirstOption" แทน "0" หรือ "1")

ในทำนองเดียวกันข้อความทั่วไปดังนี้CamelCasing ดังนั้นแทนที่จะเป็น "string" XML ต้องการ "String" นี่คือสาเหตุที่ Boolean.TrueString เป็น "จริง" และ Boolean.FalseString เป็น "เท็จ" โดยค่าเริ่มต้น


7
ตลกที่บูลีน XML จะแตกถ้าคุณตั้งค่าเป็น "จริง" และไม่ใช่ "จริง"? - "โปรดทราบว่า XML คำนึงถึงตัวพิมพ์เล็กและตัวย่อ XML ยอมรับ" true "และ" false "เป็นชุดค่าบูลีนที่ถูกต้อง"
PandaWood

-1

นี่อาจเป็นสิ่งที่เลวร้ายยิ่งจาก VB ไม่ใช่. Net วันเก่าเมื่อ bool.ToString สร้างจริงหรือเท็จ


3
ก่อนหน้า. NET ประเภทข้อมูลบูลีนใน VB (อันที่จริงประเภทข้อมูลทั้งหมด) ไม่มีวิธีการ
Sam Axe

1
ใน VB6 คุณยังสามารถแปลงชนิดบูลีนเป็นสตริงได้ (วิธีที่ง่ายที่สุดในการกำหนดให้กับตัวแปรสตริง) สิ่งที่แปลกเกี่ยวกับเรื่องนี้คือการแปลงนั้นเป็นวัฒนธรรมเฉพาะดังนั้นหากภาษาวัฒนธรรมของคุณบนคอมพิวเตอร์ที่ใช้เป็นภาษานอร์เวย์ผลที่ได้คือ "Sann" และ "Usann" แทนที่จะเป็น "จริง" และ "เท็จ"! ปัญหานี้มักจะทำให้เกิดปัญหาหากการตั้งค่าบูลีนถูกเก็บไว้ในไฟล์ข้อความและส่งออกไปยังสภาพแวดล้อมที่แตกต่างกันซึ่งคอมพิวเตอร์ถูกตั้งค่าด้วยวัฒนธรรมอังกฤษ (สหรัฐอเมริกา)
ความกลัว
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.