Tại sao tôi nên triển khai ICloneable trong c #?


110

Bạn có thể giải thích cho tôi lý do tại sao tôi nên kế thừa ICloneablevà triển khaiClone() phương thức?

Nếu tôi muốn tạo một bản sao sâu, tôi không thể thực hiện phương pháp của mình? Hãy nói MyClone()?

Tại sao tôi nên thừa kế từ ICloneable? Các lợi thế là gì? Nó chỉ là một vấn đề làm cho mã "dễ đọc hơn"?


Câu trả lời:


117

Bạn không nên. Microsoft khuyên bạn không nên triển khai ICloneablevì không có dấu hiệu rõ ràng từ giao diện cho dù Clonephương pháp của bạn thực hiện một bản sao "sâu" hay "nông".

Xem bài đăng trên blog này của Brad Abrams vào năm 2003 (!) Để biết thêm thông tin.


4
Liên kết Wayback để bài viết, mà là 404 bây giờ: web.archive.org/web/20040419170407/http://blogs.msdn.com/brada/...
Harpo


29

các ICloneablegiao diện của bản thân không phải là rất hữu ích, mà là để nói rằng có thực sự không có nhiều tình huống mà nó là hữu ích để biết rằng một đối tượng là cloneable mà không biết bất cứ điều gì khác về nó. Đây là một tình huống rất khác với ví dụ IEnumerablehoặc IDisposable; Có rất nhiều tình huống hữu ích khi chấp nhận một IEnumerablemà không biết bất cứ điều gì khác ngoài cách liệt kê nó.

Mặt khác, ICloneablecó thể hữu ích khi được áp dụng như một ràng buộc chung cùng với các ràng buộc khác. Ví dụ, một lớp cơ sở có thể hỗ trợ một cách hữu ích một số dẫn xuất, một số trong số đó có thể được sao chép một cách hữu ích và một số thì không. Nếu bản thân kiểu cơ sở lộ ra giao diện sao chép công khai, thì bất kỳ kiểu phái sinh nào không thể được sao chép sẽ vi phạm Nguyên tắc thay thế Liskov. Cách để tránh vấn đề này là để kiểu cơ sở hỗ trợ sao chép bằng phương pháp được Bảo vệ và cho phép các kiểu dẫn xuất triển khai giao diện nhân bản công khai khi chúng thấy phù hợp.

Khi điều đó đã được hoàn thành, một phương thức muốn chấp nhận một đối tượng của một WonderfulBasekiểu và cần có khả năng sao chép nó, có thể được mã hóa để chấp nhận một đối tượng WonderfulBase hỗ trợ sao chép (sử dụng một tham số kiểu chung với kiểu cơ sở và các ICloneableràng buộc) . Mặc dù ICloneablebản thân giao diện sẽ không chỉ ra nhân bản sâu hay nông, nhưng tài liệu về WonderfulBasesẽ cho biết liệu có WonderfulBasethể nhân bản nên được nhân bản sâu hay nông. Về cơ bản, ICloneablegiao diện sẽ không thực hiện được bất kỳ điều gì không thể hoàn thành bằng cách xác định ICloneableWonderfulBase, ngoại trừ việc nó sẽ tránh phải xác định các tên khác nhau cho mọi lớp cơ sở có thể nhân bản khác nhau.


18

ICloneablelà một trong những hiện vật trong BCL đã gây tranh cãi. Không có lý do thực sự để IMHO thực hiện nó. Với điều đó đã nói nếu tôi định tạo một phương thức sao chép thì tôi sẽ triển khai ICloneablevà tôi cung cấp phiên bản được đánh máy mạnh mẽ của riêng mìnhClone .

Vấn đề ICloneablelà nó không bao giờ được chỉ ra nếu Clonelà một bản sao nông hay một bản sao sâu, đó là những thứ rất khác nhau. Thực tế là không ICloneable<T>có dấu hiệu cho thấy suy nghĩ của Microsoft về ICloneable


9

Matt là chính xác, không sử dụng nó. Tạo Copy()phương thức của riêng bạn (hoặc tên tương tự) và làm cho nó hoàn toàn rõ ràng trong API công khai của bạn cho dù phương pháp của bạn đang tạo bản sao sâu hay nông của đối tượng của bạn.

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.