Tại sao Convert.ToString (null) trả về một giá trị khác nếu bạn ép kiểu null?


116
Convert.ToString(null)

trả lại

null

Đúng như tôi mong đợi.

Nhưng

Convert.ToString(null as object)

trả lại

""

Tại sao những điều này lại khác nhau?

Câu trả lời:


143

Có 2 quá tải trong số ToStringđó hoạt động ở đây

Convert.ToString(object o);
Convert.ToString(string s);

Trình biên dịch C # về cơ bản cố gắng chọn quá tải cụ thể nhất sẽ hoạt động với đầu vào. Một nullgiá trị chuyển đổi thành bất kỳ loại tài liệu tham khảo. Trong trường hợp stringnày cụ thể hơn objectvà do đó nó sẽ được chọn là người chiến thắng.

Trong phần null as objectbạn đã củng cố loại biểu thức là object. Điều này có nghĩa là nó không còn tương thích với stringquá tải và trình biên dịch sẽ chọn objectquá tải vì nó tương thích duy nhất còn lại.

Các chi tiết thực sự khó hiểu về cách hoạt động của việc bẻ cà vạt này được đề cập trong phần 7.4.3 của thông số ngôn ngữ C #.


15
Đồng ý. Vì vậy, nó đang sử dụng một quá tải thay vì quá tải kia. Có ý nghĩa. Nhưng không phải cả hai quá tải đều trả về cùng một thứ? +1 btw.
John MacIntyre

2
@JohnMacIntyre - Điều đó phụ thuộc vào nhóm phát triển chứ không phải trình biên dịch.
JonH

8
@JohnMacIntyre Nếu bạn nhìn vào việc triển khai Convert.ToString(string)nó chỉ là một chức năng nhận dạng trong khi Convert.ToString(object)thực sự trải qua một con đường khó theo dõi hơn. Trong nháy mắt, tôi sẽ đồng ý rằng họ nên trả lại như cũ nhưng lớp có thể chuyển đổi của BCL không phải là thứ mà tôi rất am hiểu và có thể có lý do chính đáng cho sự khác biệt (mặc dù tôi vẫn nghi ngờ)
JaredPar

Tôi đến đây để tìm cách chuyển đổi một đối tượng null thành một chuỗi null. Câu trả lời cho người tìm kiếm khác là (string)null, hoặc nếu bạn đối tượng được gọi là o, sau đó(string)o
rayzinnz

65

Tiếp theo từ câu trả lời giải quyết quá tải tuyệt vời của JaredPar - câu hỏi vẫn là "tại sao Convert.ToString(string)trả về null, nhưng Convert.ToString(object)trả về string.Empty"?

Và câu trả lời cho điều đó là ... bởi vì các tài liệu nói như vậy :

Convert.ToString (string) trả về "phiên bản chuỗi được chỉ định; không có chuyển đổi thực tế nào được thực hiện."

Convert.ToString (đối tượng) trả về "biểu diễn chuỗi của giá trị hoặc String.Empty nếu giá trị là null."

CHỈNH SỬA: Về việc liệu đây có phải là "lỗi trong thông số kỹ thuật", "thiết kế API rất tệ", "tại sao nó lại được chỉ định như thế này", v.v. - Tôi sẽ xem xét một số lý do tại sao tôi không thấy nó như một vấn đề lớn.

  1. System.Convertcó các phương thức để chuyển đổi mọi kiểu cơ sở thành chính nó . Điều này thật kỳ lạ - vì không cần hoặc có thể chuyển đổi, vì vậy các phương thức kết thúc chỉ trả về tham số. Convert.ToString(string)cư xử như nhau. Tôi cho rằng chúng ở đây cho các tình huống tạo mã.
  2. Convert.ToString(object)có 3 lựa chọn khi được thông qua null. Ném, trả về null hoặc trả về chuỗi.Empty. Việc ném sẽ có hại - gấp đôi vì vậy với giả định chúng được sử dụng cho mã đã tạo. Trả về null yêu cầu người gọi của bạn thực hiện kiểm tra null - một lần nữa, không phải là một lựa chọn tuyệt vời trong mã đã tạo. Trả về string.Empty có vẻ là một lựa chọn hợp lý. Phần còn lại của System.Convertgiao dịch với các loại giá trị - có giá trị mặc định.
  3. Việc trả về null là "đúng" hơn, nhưng string.Empty chắc chắn có thể sử dụng được nhiều hơn. Thay đổi Convert.ToString(string)có nghĩa là phá vỡ quy tắc "không có chuyển đổi thực tế". Vì System.Convertlà một lớp tiện ích tĩnh, nên mỗi phương thức có thể được coi là của riêng nó một cách hợp lý. Có rất ít trường hợp trong thế giới thực mà hành vi này phải "đáng ngạc nhiên", vì vậy hãy để tính khả dụng chiến thắng tính đúng đắn (có thể có).

Có công bằng khi nói đó là một lỗi trong thông số kỹ thuật không?
John MacIntyre

3
điều đó không trả lời tại sao nó như thế này. Nói nó cư xử như thế này bởi vì nó đã được ghi nhận để cư xử như thế này là có tính chất phản cảm.
CodesInChaos

2
@JohnMacIntyre IMO, công bằng mà nói thì đó là thiết kế API rất tệ.
CodesInChaos

7
@CodeInChaos - không phải là một sự phản bác, trừ khi bạn cho rằng tài liệu được viết dựa trên hành vi quan sát được sau khi BCL được phát triển. Tôi nghĩ đó là một giả định kỳ lạ. IOW, nó không phải là "tài liệu để cư xử như thế này", nó "được ghi lại rằng nó sẽ hoạt động như thế này" - tức là, nó " được chỉ định để hoạt động như thế này".
Mark Brackett

8
Nó chỉ thay đổi các câu hỏi để "tại sao nó đã được chỉ định để hành xử như thế này"
CodesInChaos
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.