Tại sao / khi nào thì thích hợp để ghi đè ToString?


103

Tôi đang học C # và tôi tự hỏi điểm và lợi ích của việc ghi đè ToStringcó thể là gì, như thể hiện trong ví dụ bên dưới.

Điều này có thể được thực hiện theo một số cách đơn giản hơn, sử dụng một phương pháp chung mà không cần ghi đè?

public string GetToStringItemsHeadings
{
    get { return string.Format("{0,-20} {1, -20}", "Office Email", "Private Email"); }
}


public override string ToString()
{
    string strOut = string.Format("{0,-20} {1, -20}", m_work, m_personal);
    return strOut;
}

4
Tùy thuộc vào việc bạn thực sự muốn sử dụng nó để hiển thị đối tượng trong giao diện người dùng ở bất kỳ đâu, nếu không nó thường chỉ để gỡ lỗi - bạn sẽ thấy đầu ra ToString trong cửa sổ xem của VS. (Nhưng bạn cũng có thể đạt được điều đó với các thuộc tính trên lớp.) Vì bạn đã có các tiêu đề và xuất ra, có vẻ như chương trình này đang sử dụng nó để loại bỏ đối tượng bằng cách sử dụng Console.WriteLine(obj.GetToStringItemsHeadings); Console.WriteLine(obj);hoặc tương tự.
Rup

2
Tôi không thực sự hiểu câu hỏi. Nó có thể được thực hiện khác không? Đúng. Nhưng tại sao bạn lại muốn làm khác đi.
Konrad Rudolph

5
Tôi thực sự sẽ bỏ qua GetToStringtên thuộc tính ... Sau đó, bạn sẽ lấy ví dụConsole.WriteLine(obj.ItemHeadings)
Svish

và thay đổi thuộc tính ItemHeadings thành static vì nó không cần bất kỳ "this".
eFloh

Bạn có thể muốn kiểm tra câu hỏi này: stackoverflow.com/questions/7906828/oo-design-advice-tostring
Yuri Ghensev

Câu trả lời:


127
  • Bạn có cần ghi đè ToString? Không.

  • Bạn có thể lấy biểu diễn chuỗi của đối tượng của mình theo cách khác không? Đúng.

Nhưng bằng cách sử dụng, ToStringbạn đang sử dụng một phương thức chung cho tất cả các đối tượng và do đó các lớp khác biết về phương thức này. Ví dụ: bất cứ khi nào .NET framework muốn chuyển đổi một đối tượng thành biểu diễn chuỗi, ToStringlà một ứng cử viên chính (có những đối tượng khác, nếu bạn muốn cung cấp các tùy chọn định dạng phức tạp hơn).

Cụ thể,

Console.WriteLine(yourObject);

sẽ gọi yourObject.ToString().


13
Đúng. Ngoài ra, điều này rất hữu ích trong phát triển MVC hoặc ASP.Net ở đâu @yourObject<%=yourObject%>sẽ là "ToString-ed".
Ben Lesh

4
Ngoài ra khi Populating một combobox, ToString là cuộc gọi mặc định để có được những văn bản mục
Davi Fiamenghi

3
Hãy coi chừng thực hành như vậy. Câu chuyện có thật: một sinh viên ghi đè ToString bằng một phương thức mà bên cạnh việc trả về một chuỗi, đã thay đổi dữ liệu. Anh ta đang gỡ lỗi chương trình nhưng trong khi chương trình đang đứng ở điểm ngắt, giá trị liên tục thay đổi. Rõ ràng - mỗi lần anh ta kiểm tra giá trị ToString đã được thực thi - vì vậy giá trị đã thay đổi ngay cả khi chương trình không chạy.
JNF

3
@JNF "Thực hành như vậy" là gì? ToStringthực sự không nên thay đổi trạng thái của một đối tượng. Nhưng đây không phải là điều tôi ủng hộ.
Konrad Rudolph

8
@JNF Tôi không chấp nhận điều đó. ToStringđược có nghĩa là để được ghi đè. Giai đoạn = Stage. Đặt một lời cảnh báo trước tuyên bố này không có hiệu quả. Nếu bạn làm sai - lỗi của chính bạn. Trên thực tế, học sinh của bạn đã vi phạm điểm 4 trong danh sách chính thức các hướng dẫn về ghi đè ToStringđã được đăng trong câu trả lời của David Anderson.
Konrad Rudolph

129

Tôi chỉ sẽ cung cấp cho bạn câu trả lời trực tiếp từ Hướng dẫn thiết kế khung từ Chuỗi phát triển .NET.

TRÁNH đưa ra các ngoại lệ từToString

CONSIDER trả về một chuỗi duy nhất được liên kết với phiên bản.

CONSIDER có đầu ra ToStringlà đầu vào hợp lệ cho bất kỳ phương thức phân tích cú pháp nào trên loại này.

NÊN đảm bảo rằng ToStringkhông có tác dụng phụ có thể quan sát được.

NÊN báo cáo thông tin nhạy cảm về bảo mật thông qua việc ghi đè ToStringchỉ sau khi yêu cầu sự cho phép thích hợp. Nếu yêu cầu quyền không thành công, hãy trả về một chuỗi loại trừ thông tin nhạy cảm về bảo mật.

Các Object.ToStringphương pháp được thiết kế để được sử dụng để trưng bày tổng quát và mục đích gỡ lỗi. Việc triển khai mặc định chỉ đơn giản là cung cấp tên loại đối tượng. Việc triển khai mặc định không hữu ích lắm và bạn nên ghi đè phương thức này.

NÊN ghi đè ToStringbất cứ khi nào một chuỗi thú vị mà con người có thể đọc được có thể được trả về. Việc triển khai mặc định không hữu ích lắm và việc triển khai tùy chỉnh hầu như luôn mang lại nhiều giá trị hơn.

NÊN thích một cái tên thân thiện hơn một ID duy nhất nhưng không thể đọc được.

Điều đáng nói nữa là Chris Sells cũng giải thích trong các hướng dẫn ToStringthường gây nguy hiểm cho giao diện người dùng. Nói chung, quy tắc chung của tôi là để lộ một thuộc tính sẽ được sử dụng để ràng buộc thông tin với giao diện người dùng và để lại quyền ToStringghi đè hiển thị thông tin chẩn đoán cho nhà phát triển. Bạn cũng có thể trang trí kiểu của mình DebuggerDisplayAttribute.

NÊN cố gắng giữ cho chuỗi được trả về ToStringngắn. Trình gỡ lỗi sử dụng ToStringđể có được một biểu diễn văn bản của một đối tượng để hiển thị cho nhà phát triển. Nếu chuỗi dài hơn trình gỡ lỗi có thể hiển thị, trải nghiệm gỡ lỗi bị cản trở.

NÊN định dạng chuỗi dựa trên văn hóa luồng hiện tại khi trả về thông tin phụ thuộc vào văn hóa.

NÊN cung cấp quá tải ToString(string format)hoặc triển khai IFormattable, nếu chuỗi trả về từ ToStringnhạy cảm với văn hóa hoặc có nhiều cách khác nhau để định dạng chuỗi. Ví dụ, DateTimecung cấp quá tải và triển khai IFormattable.

KHÔNG trả về một chuỗi rỗng hoặc null từToString

Tôi thề với những nguyên tắc này, và bạn nên làm như vậy. Tôi không thể cho bạn biết mã của tôi đã được cải thiện như thế nào chỉ bằng một hướng dẫn này ToString. Điều tương tự cũng xảy ra với những thứ như IEquatable(Of T)IComparable(Of T). Những điều này làm cho mã của bạn rất hoạt động và bạn sẽ không hối tiếc khi dành thêm thời gian để triển khai bất kỳ mã nào trong số đó.

Cá nhân tôi chưa bao giờ thực sự sử dụng ToString nhiều cho các giao diện người dùng, tôi đã luôn tiếp xúc với một thuộc tính hoặc phương pháp nào đó. Phần lớn thời gian bạn nên sử dụng ToStringcho mục đích gỡ lỗi và nhà phát triển. Sử dụng nó để hiển thị thông tin chẩn đoán quan trọng.


6
Rất hay, đây có phải là những nguyên tắc mà bạn tham khảo msdn.microsoft.com/en-us/library/ms229042.aspx không?
Jodrell

2
@Jodrell Tôi tin rằng nó được lấy từ Nguyên tắc thiết kế khung
Jim Schubert

6
Cần trích dẫn tốt hơn.
Ben Voigt

13
Tôi không biết SO đã được chuyển thành Wikipedia.
David Anderson,

14
Không phải vậy, nhưng khi bạn trích dẫn các nguyên tắc, việc cung cấp nguồn là một điểm cộng không thể chối cãi.
Falanwe

39

Ghi đè ToString()cho phép bạn cung cấp một biểu diễn chuỗi hữu ích mà con người có thể đọc được của một lớp.

Điều này có nghĩa là đầu ra có thể tiết lộ thông tin hữu ích về lớp của bạn. Ví dụ: nếu bạn có một lớp Person, bạn có thể chọn để có ToString()đầu ra là id của người đó, họ của họ, họ của họ, v.v. Điều này cực kỳ hữu ích khi gỡ lỗi hoặc ghi nhật ký.

Đối với ví dụ của bạn - rất khó để biết liệu ghi đè của bạn có hữu ích hay không nếu không biết lớp này là gì - nhưng bản thân việc triển khai là ổn.


13

Nó luôn phù hợp nhưng hãy cân nhắc kỹ lưỡng ý định đằng sau những gì bạn đang hiển thị

Một câu hỏi tốt hơn sẽ là hỏi:

Tại sao một người sẽ ghi đè ToString ()?

ToString () là cửa sổ chuyển sang trạng thái của một đối tượng. Nhấn mạnh vào trạng thái như một yêu cầu. Các ngôn ngữ OOP mạnh như Java / C # lạm dụng mô hình OOP bằng cách đóng gói mọi thứ trong một lớp. Hãy tưởng tượng bạn đang viết mã bằng một ngôn ngữ không tuân theo mô hình OOP mạnh mẽ; cân nhắc xem bạn sẽ sử dụng một lớp hay một hàm. Nếu bạn sử dụng nó như một hàm (tức là động từ, hành động) và trạng thái bên trong chỉ được duy trì tạm thời giữa đầu vào / đầu ra, thì ToString () sẽ không thêm giá trị.

Giống như những người khác đã đề cập, điều quan trọng là phải xem xét những gì bạn xuất ra với ToString () vì nó có thể được sử dụng bởi trình gỡ lỗi hoặc các hệ thống khác.

Tôi thích hình dung phương thức ToString như là tham số --help của một đối tượng. Nó phải ngắn gọn, dễ đọc, rõ ràng và dễ hiển thị. Nó sẽ hiển thị những gì đối tượng không phải những gì nó làm . Với tất cả những điều đó, chúng ta hãy xem xét ...

Trường hợp sử dụng - Phân tích cú pháp một gói TCP:

Không phải là một bản chụp mạng chỉ cấp ứng dụng mà là một thứ gì đó hấp dẫn hơn như một bản chụp pcap.

Bạn chỉ muốn quá tải ToString () cho lớp TCP để bạn có thể in dữ liệu ra bảng điều khiển. Nó sẽ bao gồm những gì? Bạn có thể phát điên và phân tích cú pháp tất cả các chi tiết TCP (tức là TCP rất phức tạp) ...

Bao gồm:

  • Cổng nguồn
  • Cảng đích
  • Số thứ tự
  • Số xác nhận
  • Phần bù dữ liệu
  • Cờ
  • Chênh lệch cửa sổ
  • Checksum
  • Con trỏ khẩn cấp
  • Tùy chọn (Tôi thậm chí sẽ không đến đó)

Nhưng bạn có muốn nhận tất cả rác đó nếu bạn đang gọi TCP.ToString () trên 100 gói không? Tất nhiên là không, đó sẽ là tình trạng quá tải thông tin. Sự lựa chọn dễ dàng và rõ ràng cũng là sự hợp lý nhất ...

Cho thấy những gì mọi người mong đợi để xem:

  • Cổng nguồn
  • Cảng đích

Tôi thích một đầu ra hợp lý để con người dễ dàng phân tích cú pháp trừ YMMV .

TCP:[destination:000, source:000]

Không có gì phức tạp, đầu ra không phải để máy móc phân tích cú pháp (tức là trừ khi mọi người đang lạm dụng mã của bạn), mục đích dự kiến ​​là để con người có thể đọc được.

Nhưng còn phần còn lại của thông tin hấp dẫn mà tôi đã nói trước đây, điều đó cũng không hữu ích sao? Tôi sẽ làm điều đó nhưng trước tiên ...


ToString () một trong những phương thức có giá trị và ít được sử dụng nhất mọi thời đại

Vì hai lý do:

  1. Mọi người không hiểu ToString () dùng để làm gì
  2. Lớp 'Đối tượng' cơ sở thiếu một phương thức chuỗi khác, quan trọng không kém.

Lý do 1 - Không lạm dụng tính hữu ích của ToString ():

Rất nhiều người sử dụng ToString () để kéo một biểu diễn chuỗi đơn giản của một đối tượng. Hướng dẫn sử dụng C # thậm chí còn nêu rõ:

ToString là phương pháp đị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ị.

Hiển thị, không phải xử lý thêm. Điều đó không có nghĩa là, hãy lấy biểu diễn chuỗi đẹp của tôi về gói TCP ở trên và kéo cổng nguồn bằng cách sử dụng regex :: cringe ::.

Cách đúng đắn để thực hiện công việc là gọi ToString () trực tiếp trên thuộc tính SourcePort (BTW là một ushort nên ToString () đã có sẵn).

Nếu bạn cần một thứ gì đó mạnh mẽ hơn để đóng gói trạng thái của một đối tượng phức tạp để phân tích cú pháp máy, bạn nên sử dụng chiến lược tuần tự hóa có cấu trúc.

May mắn thay, các chiến lược như vậy rất phổ biến:

  • ISerializable (C #)
  • Dưa chua (Python)
  • JSON (Javascript hoặc bất kỳ ngôn ngữ nào triển khai nó)
  • XÀ BÔNG TẮM
  • Vân vân...

Lưu ý: Trừ khi bạn đang sử dụng PHP vì herp-derp, có một chức năng cho điều đó :: snicker ::

Lý do 2 - ToString () là không đủ:

Tôi vẫn chưa thấy một ngôn ngữ thực hiện điều này ở cốt lõi nhưng tôi đã thấy và sử dụng các biến thể của cách tiếp cận này trong tự nhiên.

Một số trong số đó bao gồm:

  • ToVerboseString ()
  • ToString (verbose = true)

Về cơ bản, mớ hỗn độn lông lá của trạng thái Gói TCP nên được mô tả để con người có thể đọc được. Để tránh 'con ngựa bất kham' khi nói về TCP, tôi sẽ 'chỉ tay' vào trường hợp số 1 mà tôi nghĩ ToString () và ToVerboseString () chưa được sử dụng hết ...

Trường hợp sử dụng - Mảng:

Nếu bạn chủ yếu sử dụng một ngôn ngữ, bạn có thể cảm thấy thoải mái với cách tiếp cận của ngôn ngữ đó. Đối với những người như tôi, những người chuyển đổi giữa các ngôn ngữ khác nhau, số lượng các cách tiếp cận khác nhau có thể gây khó chịu.

Tức là, số lần điều này khiến tôi khó chịu lớn hơn tổng tất cả các ngón tay của mọi vị thần Hindu cộng lại.

Có rất nhiều trường hợp ngôn ngữ sử dụng chung hacks và một vàicó đượcngay . Một số yêu cầu phát minh lại bánh xe, một số làm một bãi cạn, một số khác làm một bãi sâu, không cái nào hoạt động theo cách tôi muốn ...

Những gì tôi yêu cầu là một cách tiếp cận rất đơn giản:

print(array.ToString());

Kết quả đầu ra: 'Array [x]' hoặc 'Array [x] [y]'

Trong đó x là số mục trong thứ nguyên đầu tiên và y là số lượng mục trong thứ nguyên thứ hai hoặc một số giá trị cho biết thứ nguyên thứ 2 có hình răng cưa (có thể có phạm vi tối thiểu / tối đa?).

Và:

print(array.ToVerboseString());

Xuất ra toàn bộ cô ấy bằng bản in đẹp vì tôi đánh giá cao những thứ đẹp đẽ.

Hy vọng rằng, điều này làm sáng tỏ một chủ đề đã khiến tôi khó chịu trong một thời gian dài. Ít nhất thì tôi cũng rắc một chút mồi nhử để các PHPers không tán thành câu trả lời này.


Bạn đã viết, "Tôi vẫn chưa thấy một ngôn ngữ nào thực hiện điều này ở cốt lõi". Đối với tôi, có vẻ như Python đến khá gần với điều này; ví dụ: in một mảng cung cấp cho tất cả dữ liệu của nó một cách chính xác. Đó là một điều tôi nhớ trong C # / Java, mặc dù tôi thích sự nghiêm ngặt của chúng. Và khi bạn cần vượt qua ToString (), sẽ rất tuyệt nếu có một cái gì đó như cú pháp hiểu danh sách của Python; Tôi đoán string.Join () cũng tương tự, mặc dù kém linh hoạt hơn.
Jon Coombs

1
@JCoombs Tôi không đồng ý, sự hiểu biết rất tuyệt vời. Việc duyệt các cấu trúc dữ liệu trong Python thông qua các phần hiểu được giúp cuộc sống dễ dàng hơn rất nhiều nhưng cách tiếp cận đó vẫn yêu cầu kiến ​​thức sâu sắc về cấu trúc bên trong của đối tượng. Điều gì đó không phải lúc nào cũng rõ ràng với các lớp đã được nhập từ thư viện bên ngoài. Các tác giả thư viện là cách tốt để ghi đè ToString () và cung cấp một biểu diễn hữu ích mà con người có thể đọc được.
Evan Plaice,

Điểm tuyệt vời. Vì vậy, thay vì không hiển thị gì nhiều hơn về cơ bản là một kiểu chữ, nó có thể tự động tuần tự hóa thành một thứ gì đó giống như JSON. (Cho đến nay, tôi chỉ thấy các đối tượng .NET được tuần tự hóa sang XML, nhưng tôi mới làm quen với .NET) Nhưng sau đó mối nguy hiểm có thể là sự cám dỗ để coi ToString () là máy có thể đọc được? (Ví dụ: mong đợi để có thể deserialize nó.)
Jon Coombs

1
@JCoombs Đúng, ở cấp độ chức năng, JSON và XML phục vụ cùng một mục đích. Nhiều người sử dụng ToString như một đầu ra có thể đọc được bằng máy; điều đó có xấu hay không là điều còn phải bàn cãi. Thịt bò lớn nhất của tôi - thường là - thật khó để xuất trạng thái của một đối tượng ở định dạng con người có thể đọc được. Việc triển khai ToString () thường không được tận dụng và việc đọc trạng thái của một đối tượng bên ngoài danh sách theo dõi của trình gỡ lỗi là một điều khó khăn. Các biểu diễn được tuần tự hóa tốt như một bản sao lưu để hiển thị trạng thái toàn bộ đối tượng nhưng triển khai tốt hơn ToString là lựa chọn tốt nhất.
Evan Plaice, 27/09/13

Nếu ToString()nó được dùng để gỡ lỗi, thì tại sao đó là cách duy nhất để trích xuất toàn bộ văn bản từ StringBuilder - một chức năng quan trọng?
Dan W

9

Nó thực sự là về thực hành tốt như bất cứ điều gì.

ToString()được sử dụng ở nhiều nơi để trả về biểu diễn chuỗi của một đối tượng, thường là để con người sử dụng. Thường thì cùng một chuỗi đó có thể được sử dụng để bù nước cho đối tượng (hãy nghĩ đến inthoặc DateTimechẳng hạn), nhưng đó không phải lúc nào cũng là một (ví dụ: một cây, có thể có một biểu diễn chuỗi hữu ích chỉ hiển thị một Số đếm, nhưng rõ ràng bạn không thể sử dụng để xây dựng lại nó).

Cụ thể là trình gỡ lỗi sẽ sử dụng điều này để hiển thị biến trong cửa sổ xem, cửa sổ tức thì, v.v., do đó ToStringthực sự là vô giá để gỡ lỗi.

Nói chung, kiểu như vậy thường sẽ có một thành viên rõ ràng cũng trả về một chuỗi. Ví dụ, một cặp Vĩ độ / Kinh độ có thể có ToDecimalDegreeskết quả trả về "-10, 50"chẳng hạn, nhưng nó cũng có thể có ToDegreesMinutesSeconds, vì đó là một định dạng khác cho cặp Kinh độ / Kinh độ. Sau đó, cùng loại đó cũng có thể ghi đè lên ToStringmột trong những loại đó để cung cấp 'mặc định' cho những thứ như gỡ lỗi hoặc thậm chí có khả năng cho những thứ như hiển thị trang web (ví dụ: @cấu trúc trong Razor ghi ToString()kết quả của một biểu thức không phải chuỗi vào luồng đầu ra).


6

object.ToString()chuyển đổi một đối tượng thành biểu diễn chuỗi của nó. Nếu bạn muốn thay đổi những gì được trả về khi người dùng gọi ToString()vào một lớp bạn đã tạo thì bạn cần ghi đè lên ToString()lớp đó.


6

Mặc dù tôi nghĩ rằng thông tin hữu ích nhất đã được cung cấp, tôi sẽ thêm hai xu của mình:

  • ToString()có nghĩa là được ghi đè. Việc triển khai mặc định của nó trả về tên kiểu, mặc dù đôi khi có thể hữu ích (đặc biệt là khi làm việc với nhiều đối tượng), nhưng không đủ trong phần lớn thời gian.

  • Hãy nhớ rằng, đối với mục đích gỡ lỗi, bạn có thể dựa vào DebuggerDisplayAttribute. Bạn có thể đọc thêm về nó ở đây .

  • Theo quy định, trên POCO, bạn luôn có thể ghi đè ToString(). POCO là một biểu diễn dữ liệu có cấu trúc, thường có thể trở thành một chuỗi.

  • Thiết kế ToString trở thành một biểu diễn văn bản cho đối tượng của bạn. Có thể là các trường và dữ liệu chính của nó, có thể là mô tả về số lượng mục có trong bộ sưu tập, v.v.

  • Luôn cố gắng sắp xếp chuỗi đó thành một dòng duy nhất và chỉ có thông tin cần thiết. Nếu bạn có một Personlớp với các thuộc tính Tên, Địa chỉ, Số, v.v., chỉ trả về dữ liệu chính (Đặt tên cho một số số ID).

  • Hãy cẩn thận để không ghi đè việc triển khai tốt ToString(). Một số lớp khung đã được triển khai ToString(). Ghi đè việc triển khai mặc định đó là một điều tồi tệ: mọi người sẽ mong đợi một kết quả nhất định ToString()và nhận được một kết quả khác.

Đừng thực sự sợ hãi khi sử dụng ToString(). Điều duy nhất tôi phải cẩn thận là trả lại thông tin nhạy cảm. Ngoài ra, rủi ro là tối thiểu. Chắc chắn, như một số đã chỉ ra, các lớp khác sẽ sử dụng ToString của bạn bất cứ khi nào tiếp cận thông tin. Nhưng heck, khi nào trả về tên loại sẽ được coi là tốt hơn việc lấy một số thông tin thực tế?


5

Nếu bạn không ghi đè ToStringthì bạn sẽ nhận được triển khai các lớp cơ sở của mình, Objectnó chỉ là tên kiểu ngắn của lớp.

Nếu bạn muốn một số triển khai khác, có ý nghĩa hơn hoặc hữu ích hơn ToStringthì hãy ghi đè nó.


Điều này có thể hữu ích khi sử dụng danh sách loại của bạn làm nguồn dữ liệu cho một ListBoxdanh sách ToStringsẽ được hiển thị tự động.

Một tình huống khác xảy ra khi bạn muốn chuyển loại của mình String.Formatmà gọi ToStringđến để có được đại diện cho loại của bạn.


4

Điều gì đó chưa ai đề cập đến: Bằng cách ghi đè ToString(), bạn cũng có thể xem xét triển khai IFormattableđể bạn có thể làm như sau:

 public override ToString() {
   return string.Format("{0,-20} {1, -20}", m_work, m_personal);
 }

 public ToString(string formatter) {
   string formattedEmail = this.ToString();
   switch (formatter.ToLower()) {
     case "w":
       formattedEmail = m_Work;
       break;
     case "p":
       formattedEmail = m_Personal;
       break;
     case "hw":
       formattedEmail = string.Format("mailto:{0}", m_Work);
       break;
   }
   return formattedEmail;
}

Cái nào có thể hữu ích.


Bạn có thể vui lòng cho một ví dụ về một lớp framwork cung cấp phương thức đó để ghi đè? Thứ liên quan duy nhất mà tôi biết trong khuôn khổ là IFormattiblegiao diện.
tm1

@ tm1 Bất kỳ đối tượng nào kế thừa System.Objectsẽ có một ToString()phương thức có thể ghi đè , nhưng bạn nói đúng rằng phương thức định dạng không nên overridevà thực sự nên tham chiếu IFormattiblegiao diện để hoàn toàn phù hợp.
Zhaph - Ben Duguid,

Hầu như - IFormattablenhận một IFormatProvidertham số. Cảm ơn bạn đã chỉnh sửa bài viết của mình.
tm1

Trên thực tế, nó có hai phương pháp, giá trị tôi đã thể hiện được trong một thể hiện;)
Zhaph - Ben Duguid

3

Một lợi ích của việc ghi đè ToString () là hỗ trợ công cụ của Resharper: Alt + Ins -> "Định dạng thành viên" và nó ghi ToString () cho bạn.


2

Trong một số trường hợp, việc đọc các giá trị của các lớp tùy chỉnh trong cửa sổ theo dõi trình gỡ lỗi trở nên dễ dàng hơn. Nếu tôi biết chính xác những gì tôi muốn xem trong cửa sổ xem, khi tôi ghi đè ToString bằng thông tin đó, thì tôi sẽ thấy nó.


1

Khi xác định các cấu trúc (một cách hiệu quả là nguyên tắc của người dùng), tôi thấy rằng thực hành tốt là có các đối sánh ToStringParseTryParsecác phương thức, đặc biệt là đối với tuần tự hóa XML. Trong trường hợp này, bạn sẽ chuyển đổi toàn bộ trạng thái thành một chuỗi để có thể đọc nó từ sau này.

Tuy nhiên, các lớp là các cấu trúc phức hợp hơn thường sẽ quá phức tạp để sử dụng ToStringParse. Các ToStringphương pháp của chúng , thay vì lưu toàn bộ trạng thái, có thể là một mô tả đơn giản giúp bạn xác định trạng thái của chúng, như một số nhận dạng duy nhất như tên hoặc ID hoặc có thể là một số lượng cho một danh sách.

Ngoài ra, như Robbie đã nói, ghi đè ToStringcho phép bạn gọi ToStringmột tham chiếu cơ bản như kiểu object.


1

Bạn có thể sử dụng nó khi bạn có một đối tượng không có ý nghĩa trực quan của biểu diễn chuỗi, chẳng hạn như người. Vì vậy, nếu bạn cần ví dụ để in người này, bạn có thể sử dụng ghi đè này để chuẩn bị định dạng của nó.


1

Các Object.ToStringphương pháp được sử dụng cho mục đích duy nhất gỡ lỗi. Việc triển khai mặc định hiển thị tên kiểu đối tượng không hữu ích lắm. Cân nhắc ghi đè phương pháp này để cung cấp thông tin tốt hơn cho việc chẩn đoán và gỡ lỗi. Vui lòng lưu ý rằng cơ sở hạ tầng ghi nhật ký cũng thường sử dụng phương thức ToString và do đó bạn sẽ tìm thấy các đoạn văn bản này trong tệp nhật ký của mình.

Không trả về tài nguyên văn bản đã bản địa hóa trong Object.ToStringphương thức. Lý do là phương thức ToString phải luôn trả về thứ gì đó mà nhà phát triển có thể hiểu được. Nhà phát triển có thể không nói được tất cả các ngôn ngữ mà ứng dụng hỗ trợ.

Thực hiện các IFormattablegiao diện khi bạn muốn trả về một văn bản cục bộ do người dùng thân thiện. Giao diện này xác định quá tải ToString với các tham số formatformatProvider. FormatProvider giúp bạn định dạng văn bản theo cách nhận biết văn hóa.

Xem thêm: Object.ToString và IFormattable


0

Đơn giản hơn tùy thuộc vào cách tài sản của bạn sẽ được sử dụng. Nếu bạn chỉ cần định dạng chuỗi một lần thì việc ghi đè nó không có ý nghĩa gì.

Tuy nhiên, Có vẻ như bạn đang ghi đè phương thức ToString để không trả về dữ liệu chuỗi bình thường cho thuộc tính của bạn mà để thực hiện một mẫu định dạng chuẩn. Vì bạn đang sử dụng string.format với padding.

Bởi vì bạn nói rằng bạn đang học, bài tập dường như cũng nhấn vào các nguyên tắc cốt lõi trong lập trình hướng đối tượng liên quan đến đóng gói và tái sử dụng mã.

Chuỗi.format lấy các đối số bạn đã đặt cho phần đệm đảm bảo rằng thuộc tính sẽ được định dạng giống nhau mỗi lần cho bất kỳ mã nào gọi nó. Ngoài ra, về sau, bạn chỉ phải thay đổi nó ở một nơi thay vì nhiều nơi.

Câu hỏi tuyệt vời và cũng có một số câu trả lời tuyệt vời!


0

Tôi thấy hữu ích khi ghi đè phương thức ToString trên các lớp thực thể vì nó giúp nhanh chóng xác định các vấn đề trong thử nghiệm, đặc biệt khi một xác nhận không thành công, bảng điều khiển thử nghiệm sẽ gọi phương thức ToString trên đối tượng.

Nhưng phù hợp với những gì đã được nói trước đó là đưa ra một hình ảnh đại diện có thể đọc được của con người về đối tượng được đề cập.


0

Tôi hài lòng với Nguyên tắc khung được đề cập trong các câu trả lời khác. Tuy nhiên, tôi muốn nhấn mạnh mục đích hiển thị và gỡ lỗi.

Hãy cẩn thận về cách bạn sử dụng ToStringmã của mình. Mã của bạn không nên dựa vào biểu diễn chuỗi của một đối tượng. Nếu có, bạn hoàn toàn nên cung cấp các Parsephương pháp tương ứng .

ToStringcó thể được sử dụng ở mọi nơi, nó có thể là một điểm khó khăn về khả năng bảo trì nếu bạn muốn thay đổi biểu diễn chuỗi của một đối tượng tại một thời điểm sau đó. Bạn không thể chỉ kiểm tra hệ thống phân cấp cuộc gọi trong trường hợp này để nghiên cứu xem một số mã có bị hỏng hay không.

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.