2013-08-02 30 views
6

Tôi tự hỏi điều này, vì tôi cần phải kế thừa từ StringBuilder để triển khai sự kiện TextChanged. Tôi luôn có thể tạo một trình bao bọc có chứa một chuyển đổi rõ ràng/rõ ràng/rõ ràng, nhưng điều này dường như không phải là một giải pháp thích hợp.Tại sao lớp StringBuilder được niêm phong?

May mắn là tôi có thể kế thừa từ đối tượng đang viết cho StringBuilder, vì vậy đây không thực sự là vấn đề đối với tôi, nhưng tôi vẫn tò mò về lý do lớp đó bị niêm phong.

+2

Tại sao bạn cần xử lý sự kiện "TextChanged" của StringBuilder'? Bạn là người thêm văn bản vào đó. Tôi giả định rằng các cân nhắc về hiệu suất vượt quá khả năng mở rộng cho nó. –

+0

@Tim Điều gì sẽ xảy ra nếu nó là một 'StringWriter' hoặc một số hàm gốc như' SendMessage'? Ngoài ra, các sự kiện thường đẹp hơn để làm việc hơn là phải viết mã như 'void WriteToBuilder (StringBuilder sb, chuỗi văn bản)'. – KappaG3

+2

["Thiết kế và tài liệu thừa kế hoặc người khác cấm nó"] (http://martinfowler.com/bliki/DesignedInheritance.html) – dasblinkenlight

Trả lời

12

Điều này hơi khó trả lời. Câu trả lời upvoted có một vấn đề, StringBuilder không có bất kỳ phương thức ảo nào. Vì vậy, không có gì bạn có thể làm để ngắt lớp học hoặc làm bất cứ điều gì "thêm" không an toàn.

Tôi cho rằng lý do có thể là CLR có kiến ​​thức đặc biệt của lớp học. Đó là một chút nhàm chán đối với StringBuilder, so với các loại .NET khác mà nó thân mật với, marshaller pinvoke biết lớp đó trông như thế nào. Bạn sử dụng nó khi bạn cần truyền một tham chiếu chuỗi tới mã không được quản lý, cho phép nó viết nội dung chuỗi. Cần thiết vì đó không phải là hợp pháp đối với String, nó là bất biến. Các marshaller pinvoke biết làm thế nào để thiết lập các thành viên nội bộ của StringBuilder một cách chính xác sau khi cuộc gọi pinvoke. Nhưng sẽ không biết làm thế nào để làm điều đó cho lớp học có nguồn gốc của bạn. Rủi ro cắt lát đó không chính xác đáng được lợi ích khi không niêm phong nó. Đặc biệt vì nó không có các phương thức ảo nên bạn không thể ghi đè lên hành vi của nó.

Một phương pháp mở rộng khác là giải pháp rất hợp lý.

+0

nó có thể không có bất kỳ thứ gì ảo nhưng nó có thứ gì đó tệ hơn nhiều ... thành viên công khai trực tiếp được đánh dấu 'nội bộ', không chắc CLR sẽ giải quyết điều đó như thế nào ... hoặc nếu nó ngăn chặn lớp dẫn xuất khỏi sửa đổi chúng. – Mgetz

+0

Đó là một cái gì đó * rất * khác nhau, nó chỉ có nghĩa là phương pháp được thực hiện trong C + + thay vì C#. Backgrounder [là ở đây] (http://stackoverflow.com/questions/8870442/how-is-math-pow-implemented-in-net-framework/8870593#8870593) –

+0

"StringBuilder không có bất kỳ phương pháp ảo" âm thanh một chút sai. Mỗi đối tượng bao gồm các phương thức ảo cho bằng/hashcode và ghi đè điều này (đặc biệt là đối với chuỗi) có thể làm cho toàn bộ hệ thống gặp sự cố. –

6

StringBuilder được niêm phong vì nó lắp ráp các chuỗi, ví dụ: không bao giờ nên có một lý do để kế thừa từ nó bởi vì bất kỳ việc sử dụng nào cũng nên được giới hạn trong phạm vi. StringBuilder không thay thế cho string và không bao giờ được sử dụng theo cách đó. Mục tiêu của lớp là có cách dễ dàng xử lý bất kỳ hoạt động nào yêu cầu các chuỗi có thể thay đổi mà không bị phạt. Như vậy Không có cách nào kế thừa từ StringBuilder sẽ cung cấp bất kỳ tiện ích nào và sẽ tạo ra các vấn đề bảo mật có thể xảy ra khi lớp giao dịch với các chuỗi có thể thay đổi.

Hãy xem reference source nó không phải là một lớp đơn giản mà là một tiện ích tập trung chặt chẽ. Hơn nữa nó làm những việc là unsafe, và do đó cho phép thừa kế sẽ cho phép sửa đổi mã không an toàn mà có thể thỏa hiệp an ninh.

+1

Tôi hiểu. Nhưng sau đó một lần nữa, họ không thể chỉ đơn giản là niêm phong * những thứ nguy hiểm để ghi đè *? Không cần phải niêm phong hoàn toàn lớp học. Ngoài ra, hầu hết các thành viên của nó dường như là nội bộ, vì vậy kế thừa thậm chí sẽ không hiển thị chúng. – KappaG3

+0

@ KappaG3 bạn đã xem qua lớp ... 'unsafe' được sử dụng trong hầu hết mọi chức năng. Mục đích là tốc độ với bảo mật, không mở rộng như nó đã được giả định (khá chính xác như tôi vẫn chưa thấy một trường hợp sử dụng) mà không ai sẽ cần phải mở rộng nó. – Mgetz

+4

@ KappaG3: vì 'StringBuilder' được dự định sử dụng các phương thức bên trong để giải quyết chuỗi nhiệm vụ - xây dựng đặc biệt ở đây và bây giờ. Nó thậm chí không nên là một phần của hợp đồng công khai của bất kỳ loại nào. – Dennis