เหตุใดฉันจึงควรใช้ ICloneable ใน c #


111

คุณช่วยอธิบายให้ฉันฟังได้ไหมว่าทำไมฉันจึงควรสืบทอดICloneableและใช้Clone()วิธีนี้

หากฉันต้องการทำสำเนาลึกฉันไม่สามารถใช้วิธีการของฉันได้หรือไม่? กันMyClone()บ้างเอ่ย?

ทำไมต้องรับมรดกจากICloneable? ข้อดีคืออะไร? เป็นเพียงเรื่องของการทำให้โค้ด "อ่านง่ายขึ้น" หรือไม่?


คำตอบ:


117

คุณไม่ควร Microsoft ไม่แนะนำให้ใช้งานICloneableเนื่องจากไม่มีข้อบ่งชี้ที่ชัดเจนจากอินเทอร์เฟซว่าCloneวิธีการของคุณทำการโคลนแบบ "ลึก" หรือ "ตื้น"

ดูบล็อกโพสต์นี้จาก Brad Abramsในปี 2003 (!) สำหรับข้อมูลเพิ่มเติม


4
ลิงค์ Wayback ไปยังบทความซึ่งตอนนี้คือ 404: web.archive.org/web/20040419170407/http://blogs.msdn.com/brada/…
harpo

2
ลิงค์ที่ดีกว่า: blogs.msdn.microsoft.com/brada/2004/05/03/…
Eric Lippert

29

ICloneableอินเตอร์เฟซด้วยตัวเองไม่ได้เป็นประโยชน์มากซึ่งเป็นที่จะบอกว่ามีจริงๆไม่ได้หลาย ๆ สถานการณ์ที่เป็นประโยชน์ที่จะรู้ว่าวัตถุอยู่ cloneable โดยไม่ทราบว่าสิ่งอื่นใดเกี่ยวกับเรื่องนี้ นี่เป็นสถานการณ์ที่แตกต่างจากเช่นIEnumerableหรือIDisposable; มีหลายสถานการณ์ที่เป็นประโยชน์ในการยอมรับIEnumerableโดยไม่รู้อะไรเลยนอกจากวิธีการแจกแจง

ในทางกลับกันICloneableอาจมีประโยชน์เมื่อใช้เป็นข้อ จำกัด ทั่วไปร่วมกับข้อ จำกัด อื่น ๆ ตัวอย่างเช่นคลาสพื้นฐานอาจรองรับอนุพันธ์จำนวนหนึ่งอย่างมีประโยชน์ซึ่งบางส่วนสามารถโคลนได้อย่างมีประโยชน์และบางส่วนไม่สามารถโคลนได้ หากประเภทพื้นฐานนั้นเปิดเผยอินเทอร์เฟซการโคลนนิ่งสาธารณะประเภทอนุพันธ์ใด ๆ ที่ไม่สามารถโคลนได้จะละเมิดหลักการการแทนที่ของ Liskov วิธีหลีกเลี่ยงปัญหานี้คือการให้ประเภทฐานสนับสนุนการโคลนนิ่งโดยใช้วิธีการป้องกันและอนุญาตให้ประเภทที่ได้รับใช้อินเทอร์เฟซการโคลนสาธารณะตามที่เห็นสมควร

เมื่อทำได้สำเร็จวิธีการที่ต้องการยอมรับวัตถุWonderfulBaseประเภทหนึ่งและจำเป็นต้องสามารถโคลนได้สามารถเข้ารหัสเพื่อยอมรับวัตถุ WonderfulBase ที่รองรับการโคลน (โดยใช้พารามิเตอร์ประเภททั่วไปที่มีประเภทฐานและICloneableข้อ จำกัด ) . แม้ว่าICloneableอินเทอร์เฟซจะไม่ได้ระบุถึงการโคลนนิ่งแบบลึกหรือตื้น แต่เอกสารประกอบสำหรับWonderfulBaseระบุว่าWonderfulBaseควรโคลนแบบลึกหรือแบบตื้น โดยพื้นฐานแล้วICloneableอินเทอร์เฟซจะไม่ประสบความสำเร็จในสิ่งที่ไม่สามารถทำได้โดยการกำหนดICloneableWonderfulBaseยกเว้นว่าจะหลีกเลี่ยงการกำหนดชื่อที่แตกต่างกันสำหรับคลาสพื้นฐานที่สามารถโคลนได้


18

ICloneableเป็นหนึ่งในสิ่งประดิษฐ์เหล่านั้นใน BCL ซึ่งเป็นที่ถกเถียงกันอยู่ IMHO ไม่มีเหตุผลที่แท้จริงในการนำไปใช้ ด้วยสิ่งที่กล่าวว่าถ้าฉันจะสร้างวิธีการโคลนฉันจะใช้งานICloneableและฉันให้เวอร์ชันClone.

ปัญหาICloneableคือไม่เคยระบุว่าCloneเป็นสำเนาตื้นหรือสำเนาลึกซึ่งแตกต่างกันมาก ความจริงที่ว่าไม่มีICloneable<T>อาจบ่งชี้ถึงความคิดของ Microsoft เกี่ยวกับ ICloneable


9

แมทถูกไม่ต้องใช้ สร้างCopy()เมธอดของคุณเอง(หรือชื่อที่คล้ายกัน) และทำให้ชัดเจนใน API สาธารณะของคุณว่าเมธอดของคุณกำลังสร้างสำเนาวัตถุของคุณแบบลึกหรือตื้น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.