Tại sao Boolean.ToString xuất ra True True và không phải là true true


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

Output:
True
False

Có một lý do hợp lệ cho nó là "Đúng" và không "đúng"? Nó bị hỏng khi viết XML dưới dạng kiểu boolean của XML là chữ thường và cũng không tương thích với đúng / sai của C # (mặc dù không chắc chắn về CLS).

Cập nhật

Đây là cách rất hay của tôi để khắc phục nó trong C # (để sử dụng với XML)

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

Tất nhiên, thêm 1 phương thức nữa vào ngăn xếp, nhưng loại bỏ ToLowers () ở mọi nơi.


1
Chỉ cần nghĩ rằng tôi đã đề cập đến điều này ... Tôi vừa đọc một số cách giải quyết thông minh để giải tuần tự hóa "Đúng" dưới dạng boolean trong C # trên blog msDN! xem http://bloss.msdn.com/helloworld/archive/2009/04/03/workaround-to-deserialize-true-false-USE-xmlserializer.aspx
Peter

23
Tôi sẽ thay thế return b.ToString().ToLower();bằng return b ? "true" : "false";. Sạch hơn, hiệu quả hơn, ít phụ thuộc vào một phương pháp mà về mặt lý thuyết có thể phụ thuộc vào miền địa phương (mặc dù nó không có trong các triển khai hiện tại).
Jon Hanna

1
Điều này cũng khá khó chịu khi sử dụng RestSharp để tuần tự hóa các thuộc tính công khai của một đối tượng vào QueryString để thực hiện cuộc gọi REST WebService. Nếu API REST phân biệt chữ hoa chữ thường cho các bool (ví dụ: API chỉ đường của Google) thì điều này khiến lệnh gọi API không thành công.
Carlos P

8
"ToString là phương thức định dạng chính trong .NET Framework. Nó chuyển đổi một đối tượng thành biểu diễn chuỗi của nó để nó phù hợp để hiển thị ." (Nhấn mạnh mỏ). Object.ToString không phải là một cơ chế tuần tự hóa . :)
Rytmis

1
@awe yeah, đó là loại kinh nghiệm khiến tôi phải đề phòng rủi ro lý thuyết mặc dù hiện tại nó không xảy ra.
Jon Hanna

Câu trả lời:


165

Chỉ những người từ Microsoft thực sự có thể trả lời câu hỏi đó. Tuy nhiên, tôi muốn cung cấp một số sự thật thú vị về nó;)

Đầu tiên, đây là những gì nó nói trong MSDN về phương thức Boolean.ToString () :

Giá trị trả lại

Loại: System.String

TrueString nếu giá trị của thể hiện này là true hoặc falseString nếu giá trị của thể hiện này là false.

Nhận xét

Phương thức này trả về các hằng số "Đúng" hoặc "Sai". Lưu ý rằng XML phân biệt chữ hoa chữ thường và đặc tả XML nhận ra "true" và "false" là tập hợp các giá trị Boolean hợp lệ. Nếu đối tượng String được trả về bởi phương thức ToString () sẽ được ghi vào tệp XML, thì phương thức String.ToLower của nó phải được gọi trước để chuyển đổi nó thành chữ thường.

Ở đây có một sự thật thú vị # 1: nó hoàn toàn không trả về TrueString hay falseString. Nó sử dụng chữ cứng "Đúng" và "Sai". Bạn sẽ không làm gì tốt nếu nó sử dụng các trường, bởi vì chúng được đánh dấu là chỉ đọc, vì vậy không có gì thay đổi chúng.

Phương pháp thay thế, Boolean.ToString (IFormatProvider) thậm chí còn hài hước hơn:

Nhận xét

Tham số nhà cung cấp được bảo lưu. Nó không tham gia vào việc thực hiện phương pháp này. Điều này có nghĩa là phương thức Boolean.ToString (IFormatProvider), không giống như hầu hết các phương thức có tham số nhà cung cấp, không phản ánh các cài đặt dành riêng cho văn hóa.

Giải pháp là gì? Phụ thuộc vào chính xác những gì bạn đang cố gắng làm. Dù đó là gì, tôi cá là nó sẽ yêu cầu hack;)


2
Sửa lỗi cho tôi nếu tôi sai, nhưng tôi không thấy có gì sai với lời giải thích cho Boolean.ToString(). bool.TrueStringlà một trường chỉ đọc có chứa chữ "True" được mã hóa cứng . Do đó, nói rằng nó trả về TrueStringcũng giống như nói nó trả về chữ "True" được mã hóa cứng được lưu trữ trong đó, với điều kiện là trả về một chuỗi luôn trả về giá trị và không phải là tham chiếu.
Fernando Neira

21
Kết quả quan sát được là như nhau. Việc thực hiện thì không.
Vojislav Stojkovic

1
Biên dịch C # sẽ không thay thế Boolean.TrueString bằng "True" trong kết quả được biên dịch. Nếu họ thực sự sử dụng Boolean.TrueString thì bạn có thể sử dụng sự phản chiếu để thay đổi Boolean.TrueString để trả về một phiên bản chữ thường ... tất nhiên ai biết điều gì sẽ phá vỡ. Bạn vẫn có thể sử dụng sự phản chiếu để thay thế phương thức ToString trên Boolean để nó trả về các biến thể chữ thường.
Dewey Vozel

2
@FernandoNeira, nếu ngày mai chữ cứng TrueStringđược thay đổi, giả sử, thành chữ thường "đúng", phương thức bool.ToString()vẫn sẽ trả về trường hợp pascal "Đúng" theo nghĩa đen.
Serge

1
Tôi đổ lỗi cho Visual Basic, sử dụng True và false làm giá trị theo nghĩa đen của nó.
mrcrowl

105

... bởi vì môi trường .NET được thiết kế để hỗ trợ nhiều ngôn ngữ.

System.Boolean (trong mscorlib.dll) được thiết kế để sử dụng nội bộ bởi các ngôn ngữ để hỗ trợ kiểu dữ liệu boolean. C # sử dụng tất cả chữ thường cho các từ khóa của nó, do đó 'bool', 'true' và 'false'.

Tuy nhiên VB.NET sử dụng vỏ tiêu chuẩn: do đó 'Boolean', 'Đúng' và 'Sai'.

Vì các ngôn ngữ phải hoạt động cùng nhau, bạn không thể có true.ToString () (C #) mang lại kết quả khác cho True.ToString () (VB.NET). Các nhà thiết kế CLR đã chọn ký hiệu vỏ CLR tiêu chuẩn cho kết quả ToString ().

Đại diện chuỗi của boolean true được định nghĩa là Boolean.TrueString.

(Có trường hợp tương tự với System.String: C # trình bày nó dưới dạng loại 'chuỗi').


4
Họ phải điều chỉnh VB từ vẻ bề ngoài của mọi thứ
Chris S

5
Tôi muốn nói C # là ngôn ngữ "lẻ". Mọi thứ công khai trong .NET là CamelCase - System.Boolean, True, System.String, v.v. - đó là di sản C của C # dẫn đến việc đặt bí danh của String thành chuỗi, Boolean thành bool, True thành true, v.v. vẫn C #).
stusmith

4
Ngoài ra, lý do chính đáng (đối với tôi) là chuyển đổi sang chữ thường rất dễ trong khi thật khó để biến nó thành CamelCase, đặc biệt khi VB được sử dụng giống như @John Burns nói. Nếu không, người dùng VB không thể và sẽ không bao giờ sử dụng ToString()và họ buộc phải sử dụng như thế nào If(b, "True", "False"). Vì vậy, người dùng c # như tôi cần phải hy sinh để sử dụng ToLower():)
CallMeLaNN

2
@MarkLopez Nhận xét của bạn không chính xác, xem tại đây: msdn.microsoft.com/en-us/l Library / c8f5xwh7.aspx . Ngoài ra, tra cứu định nghĩa Boolean cho thấy trên thực tế nó là một cấu trúc và hai cái này có cùng thuộc tính.
tsTable

1
Trong khi câu trả lời của bạn làm sáng tỏ, tôi không hiểu làm thế nào "Đúng" là "chuẩn" hơn "đúng". Có vẻ như sau này là phổ biến hơn nhiều.
Nhẹ

50

Đối với Xml, bạn có thể sử dụng phương thức XmlConvert.ToString .


4
Điều này dường như cho đến nay phương pháp thanh lịch nhất. Không có lập trình bổ sung và sử dụng một thư viện chính thức thực sự được tạo ra cho mục đích đầu ra xml.
Nyerguds

25

Đó là mã đơn giản để chuyển đổi nó thành tất cả các chữ thường.

Tuy nhiên, không đơn giản để chuyển đổi "true" thành "True".

true.ToString().ToLower() 

là những gì tôi sử dụng cho đầu ra xml.


Ngoài câu trả lời @stusmith vì để hỗ trợ cho nhiều ngôn ngữ, đây là lý do tốt đẹp tại sao Microsoft thích giao diện VB của ToString()kết quả boolean .
CallMeLaNN

@Damieh: thực ra, câu hỏi là "Tại sao". Câu trả lời được chọn, không giống như điều này, thực sự đến gần với việc trả lời như có thể.
Nyerguds

1
Tốt hơn nữa; ToLowerInvariant().
quạ Vulcan

3
Bạn có thể sử dụng System.Globalization.CARMInfo.InvariantCARM.TextInfo.ToTitleCase để chuyển đổi "true" trở lại thành "True".
Jenny O'Reilly

8

Làm thế nào nó không tương thích với C #? Boolean.Pude và Boolean.TryPude không phân biệt chữ hoa chữ thường và việc phân tích cú pháp được thực hiện bằng cách so sánh giá trị với Boolean.TrueString hoặc Boolean.FalseString là "Đúng" và "Sai".

EDIT: Khi xem phương thức Boolean.ToString trong bộ phản xạ, hóa ra các chuỗi được mã hóa cứng nên phương thức ToString như sau:

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

23
Wow ... Đó có lẽ là bối cảnh duy nhất trong C # trong đó cấu trúc "if (! This)" là hợp lệ!
Tamas Czinege

2
vậy tại sao nó không trả về "sai" là những gì tôi đang hỏi
Chris S

Thật là một điều kỳ lạ để làm ... Tôi có nghĩa là đảo ngược tình trạng.
nicodemus13

6
@TamasCzinege That's probably the only context in C# where the construct "if (!this)" is valid! Bạn thách thức tôi, bạn buông thả. gist.github.com/Steinblock/10df18afb948866be1ba - Hôm nay cũng là ngày sinh nhật thứ 200 của George Boole
Jürgen Steinblock

Tự hỏi tại sao điều này không được thực hiện như return this ? "True" : "False";? (Một trường hợp bất thường khác mà bạn không thường thấy thislà một ?:điều kiện, nhưng ở đây nó sẽ có ý nghĩa.)
Darrel Hoffman

7

Tôi biết lý do tại sao nó là cách nó đã được giải quyết, nhưng khi nói đến định dạng boolean "tùy chỉnh", tôi đã có hai phương thức mở rộng mà tôi không thể sống được nữa :-)

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

Cách sử dụng là chuyện nhỏ. Sau đây chuyển đổi các giá trị bool khác nhau thành các đại diện Bồ Đào Nha của họ:

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

"Bạn có thể sử dụng các phương thức mở rộng để mở rộng một lớp hoặc giao diện, nhưng không ghi đè lên chúng. Một phương thức mở rộng có cùng tên và chữ ký như một phương thức giao diện hoặc lớp sẽ không bao giờ được gọi. Tại thời điểm biên dịch, các phương thức mở rộng luôn có mức độ ưu tiên thấp hơn phương thức cá thể được định nghĩa trong chính kiểu đó. " Giải pháp của bạn có hoạt động không? (Có thể ToString () được kế thừa do đó có thể bị ghi đè?)
jwize

1
Tôi đoán với nhận xét trước đây của tôi chữ ký này không ghi đè bất cứ điều gì.
jwize 6/10/2015

@jwize vâng, đây là những chữ ký mới, vì vậy đó là sự quá tải không phải là ghi đè ;-)
Lớn nhất

0

Lý do truelà "Đúng" là do liên kết mạnh mẽ của Microsoft với các tiêu chuẩn XML.

Từ Wikipedia : "Ngôn ngữ đánh dấu mở rộng (XML) là ngôn ngữ đánh dấu xác định một bộ quy tắc để mã hóa tài liệu theo định dạng có thể đọc được bằng con người và có thể đọc được bằng máy."

Có thể đọc được con người là chủ quan, nhưng trong con mắt của XML, sử dụng từ "Một" thay cho số "1" được ưu tiên. Bạn sẽ nhận thấy điều này xảy ra khi sử dụng enums, vì từ này được tuần tự hóa thay vì giá trị của nó ("FirstOption" thay vì "0" hoặc "1").

Tương tự như vậy, văn bản thường theo sau CamelCasing . Do đó, thay vì "chuỗi", XML thích "Chuỗi". Đây là lý do tại sao Boolean.TrueString là "Đúng" và Boolean.FalseString là "Sai" theo mặc định.


7
Thật buồn cười là boolean XML sẽ bị hỏng nếu bạn đặt nó thành "True" chứ không phải "true"? - "Lưu ý rằng XML phân biệt chữ hoa chữ thường và đặc tả XML nhận ra" đúng "và" sai "là tập hợp các giá trị Boolean hợp lệ"
PandaWood

-1

Điều này có thể ảnh hưởng từ VB cũ KHÔNG .Net ngày khi bool.ToString tạo ra Đúng hoặc Sai.


3
Trước .NET, kiểu dữ liệu Boolean trong VB (trên thực tế, tất cả các kiểu dữ liệu) không có phương thức.
Sam Axe

1
Trong VB6, bạn vẫn có thể chuyển đổi loại Boolean thành chuỗi (cách đơn giản nhất để gán nó cho biến Chuỗi). Điều kỳ lạ về điều này, là việc chuyển đổi thực sự là văn hóa cụ thể, vì vậy nếu ngôn ngữ văn hóa của bạn trên máy tính đang chạy là tiếng Na Uy, kết quả là "Sann" và "Usann" thay vì "Đúng" và "Sai"! Điều này thường gây ra sự cố nếu cài đặt boolean được lưu trữ trong tệp văn bản và được xuất sang một môi trường khác nơi máy tính được thiết lập có văn hóa tiếng Anh (Hoa Kỳ).
kinh ngạc
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.