อะไรคือจุดประสงค์ของการอ้างอิงตนเองอย่างชัดเจนใน C #?


21

ฉันกำลังประเมิน CMS โอเพนซอร์สที่ชื่อว่า Piranha ( http://piranhacms.org/ ) เพื่อใช้ในโครงการใดโครงการหนึ่งของฉัน ฉันพบรหัสต่อไปนี้น่าสนใจและสับสนเล็กน้อยอย่างน้อยสำหรับฉัน บางอย่างช่วยให้ฉันเข้าใจได้หรือไม่ว่าทำไมห้องเรียนถึงได้รับมรดกจากประเภทเดียวกัน?

public abstract class BasePage<T> : Page<T> where T : BasePage<T>
{
    /// <summary>
    /// Gets/sets the page heading.
    /// </summary>
    [Region(SortOrder = 0)]
    public Regions.PageHeading Heading { get; set; }
}

ถ้าชั้นBasePage<T>จะถูกกำหนดไว้ทำไมสืบทอดมาจากPage<T> where T: BasePage<T>? มีจุดประสงค์เฉพาะอะไรบ้าง



7
แม้จะมี downvotes และคะแนนเสียงใกล้เคียงฉันคิดว่าชุมชนนี้ผิดพลาดในอันนี้ นี่เป็นคำถามที่ระบุไว้อย่างชัดเจนเกี่ยวกับการตัดสินใจออกแบบที่เฉพาะเจาะจงและไม่สำคัญสาระสำคัญของเว็บไซต์นี้คืออะไร
Robert Harvey

เพียงแขวนไปรอบ ๆ แล้วเปิดใหม่เมื่อปิด
David Arno

อ่านแนวคิดของ polymorphism แบบ F-bounded :)
Eyvind

1
@Eyvind ฉันทำจริง สำหรับผู้ที่สนใจในการอ่านเกี่ยวกับ F-Bounded polymorphism นี่คือลิงค์staff.ustc.edu.cn/~xyfeng/teaching/FOPL/lectureNotes/
Xami Yen

คำตอบ:


13

บางอย่างช่วยให้ฉันเข้าใจได้หรือไม่ว่าทำไมห้องเรียนถึงได้รับมรดกจากประเภทเดียวกัน?

มันไม่ได้ก็สืบทอดจากPage<T>แต่Tตัวเองเป็นข้อ จำกัด BasePage<T>ที่จะแปรตามประเภทที่ได้รับมาจาก

เพื่อสรุปว่าทำไมคุณต้องดูว่าพารามิเตอร์ type Tนั้นถูกใช้งานจริงอย่างไร หลังจากขุดขึ้นมาในขณะที่คุณเลื่อนระดับของการสืบทอดคุณจะเข้าสู่ชั้นเรียนนี้:

( github )

public class GenericPage<T> : PageBase where T : GenericPage<T>
{
    public bool IsStartPage {
        get { return !ParentId.HasValue && SortOrder == 0; }
    }

    public GenericPage() : base() { }

    public static T Create(IApi api, string typeId = null)
    {
        return api.Pages.Create<T>(typeId);
    }
}

เท่าที่ฉันเห็นจุดประสงค์เดียวสำหรับข้อ จำกัด ทั่วไปคือเพื่อให้แน่ใจว่าCreateวิธีการส่งกลับชนิดนามธรรมที่เป็นไปได้น้อยที่สุด

ไม่แน่ใจว่ามันคุ้มค่าหรือเปล่า แต่อาจมีเหตุผลที่ดีอยู่เบื้องหลังหรืออาจเป็นเพียงเพื่อความสะดวกสบายหรืออาจจะไม่มีเนื้อหามากเกินไปเบื้องหลังและเป็นเพียงวิธีที่ซับซ้อนเกินไปที่จะหลีกเลี่ยงนักแสดง (BTW ฉัน ไม่ได้หมายความว่าเป็นอย่างนี้ฉันแค่บอกว่าบางคนทำอย่างนั้น)

หมายเหตุว่านี้ไม่ได้ช่วยให้พวกเขาที่จะหลีกเลี่ยงการสะท้อน - The api.Pagesเป็นที่เก็บของหน้าเว็บที่ได้รับtypeof(T).Nameและผ่านมันเป็นtypeIdไปที่contentService.Createวิธีการ ( ดูที่นี่ )


5

การใช้สิ่งนี้อย่างหนึ่งที่เกี่ยวข้องกับแนวคิดของประเภทตนเอง: พารามิเตอร์ชนิดที่แก้ไขเป็นชนิดปัจจุบัน สมมติว่าคุณต้องการกำหนดอินเทอร์เฟซด้วยclone()วิธีการ clone()วิธีการมักจะต้องกลับไปอินสแตนซ์ของระดับชั้นที่มันถูกเรียกว่า คุณประกาศวิธีนั้นอย่างไร ในระบบข้อมูลทั่วไปที่มีประเภทตนเองมันง่าย คุณเพียงแค่บอกว่ามันจะกลับselfมา ดังนั้นถ้าฉันได้เรียนวิธีการโคลนจะต้องประกาศการกลับมาFoo Fooใน Java และ (จากการค้นหาคร่าวๆ) C # นี่ไม่ใช่ตัวเลือก คุณเห็นคำประกาศเหมือนสิ่งที่คุณเห็นในชั้นนี้แทน สิ่งสำคัญคือต้องเข้าใจว่านี่ไม่ใช่สิ่งเดียวกับประเภทตัวเองและข้อ จำกัด ที่ให้ไว้นั้นอ่อนแอกว่า หากคุณมีFooและBarคลาสที่ทั้งคู่มาจากBasePageคุณสามารถ (ถ้าผมไม่ผิด) Barกำหนดฟูที่จะแปรโดย อาจเป็นประโยชน์ แต่ฉันคิดว่าโดยทั่วไปแล้วส่วนใหญ่แล้วจะใช้เป็นแบบตัวเองและเป็นที่เข้าใจว่าแม้ว่าคุณสามารถทำสิ่งรอบตัวแทนสิ่งอื่นได้ แต่ไม่ใช่สิ่งที่คุณควรทำ ฉันเล่นกับความคิดนี้มานานแล้ว แต่ก็สรุปได้ว่ามันไม่คุ้มค่ากับความพยายามเพราะข้อ จำกัด ของจาวาทั่วไป แน่นอนว่า C generics นั้นมีคุณสมบัติครบถ้วนมากกว่า แต่ดูเหมือนว่าจะมีข้อ จำกัด เดียวกันนี้

อีกครั้งที่วิธีนี้ถูกนำมาใช้คือเมื่อคุณกำลังสร้างกราฟที่มีลักษณะเหมือนต้นไม้หรือโครงสร้างแบบเรียกซ้ำ ประกาศช่วยให้ประเภทที่จะตอบสนองความต้องการของหน้า แต่ปรับแต่งประเภทเพิ่มเติม คุณอาจเห็นสิ่งนี้ในโครงสร้างแบบต้นไม้ ตัวอย่างเช่น a Nodeอาจถูกทำให้เป็นพารามิเตอร์โดยNodeอนุญาตให้การใช้งานเพื่อกำหนดว่าพวกเขาไม่ได้เป็นเพียงต้นไม้ที่มีโหนดใด ๆ แต่เป็นประเภทย่อยที่เฉพาะเจาะจงของโหนด (โดยปกติจะเป็นประเภทของตัวเอง)


3

การเป็นคนที่เขียนรหัสฉันสามารถยืนยันได้ว่าฟิลิปนั้นถูกต้องและการอ้างอิงด้วยตนเองในความเป็นจริงแล้วเป็นวิธีที่สะดวกในการสร้างวิธีการสร้างแบบพิมพ์บนชั้นฐาน

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

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