วิธีการประกาศเหตุการณ์ที่ต้องการ


14

ฉันค่อนข้างมีความสุขกับความเข้าใจโมเดลเหตุการณ์. NET ฉันคิดว่าฉันอาจเข้าใจผิดถึงความแตกต่างเล็กน้อยของระบบ

เมื่อฉันเริ่มวางกิจกรรมลงในชั้นเรียนของฉันฉันจะใช้วิธีมาตรฐานดังนี้:

public event EventHandler<MyEventArgs> MyEvent;

นี่หมายความว่าทุกสิ่งที่สมัครรับกิจกรรมจะต้องมีวิธีการดังนี้:

void HandleThatEvent(object sender, MyEventArgs args){...}

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

ดังนั้นฉันจึงเปลี่ยนเป็นการประกาศประเภทตัวแทนของฉันเอง

public delegate void MyEventHandler(SomeClass argument);

ซึ่งลดความยุ่งเหยิง แต่ทิ้งฉันด้วยปัญหาเล็ก ๆ เมื่อมันมาถึงการเขียนจัดการ:

eventImplmentor.MyEvent += HandleThatEvent;
.
.
.
void HandleThatEvent(/*oh, um, what arguments does it take? Intellisense isn't telling me*/)

ดังนั้นฉันจะต้องกลับไปที่การประกาศของผู้ได้รับมอบหมายและมองแล้วกลับไปและเขียนพวกเขาในหรือรวบรวมและรอที่จะบอก

ดังนั้นตอนนี้แทนฉันเพียงแค่ใช้Action, Action<T>หรือสิ่งที่เหมาะกับแม่แบบ

public event Action<SomeClass> MyEvent;

เพื่อให้ฉันสามารถวางเมาส์เหนือเหตุการณ์และได้รับการบอกพารามิเตอร์ที่คาดหวัง

คำถามของฉันหลังจากทั้งหมด: มีวิธีปฏิบัติที่ดีที่สุดสำหรับการประกาศเหตุการณ์ใน C # หรือไม่ ฉันควรจะกลับไปที่EventHandler<T>ทางหรือเป็นAction<T>ที่ยอมรับ?


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

คุณสามารถเขียนเหตุการณ์ที่ปลอดภัยแบบชาญฉลาด, มีค่าเฉลี่ยและแบบลีนในรหัสที่ห่อหุ้ม แต่สิ่งใดก็ตามที่คุณเผยแพร่ควรเป็นไปตามรูปแบบมาตรฐานไม่เช่นนั้นจะสร้างความสับสนให้กับผู้ใช้ในชั้นเรียนของคุณ
Martin Maat

คำตอบ:


8

สำหรับการจัดการเหตุการณ์ภายในที่เรียบง่ายมีวิธีที่ใช้ActionหรือAction<T>ตามที่คุณกำลังเสนอ ฉันมักจะใช้รูปแบบมาตรฐานรวมถึงผู้ส่งแม้กระทั่งสำหรับกิจกรรมภายในเพราะคุณไม่เคยรู้ว่าเมื่อใดคุณอาจต้องการเปิดเผยชั้นเรียนหรือกิจกรรมในภายหลังและฉันไม่ต้องการให้มีการปรับวิธีการจัดกิจกรรมใหม่ มันสาธารณะ

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

สำหรับสิ่งที่คุ้มค่าฉันใช้เวลาในการทำสิ่งนี้และเกิดรูปแบบการจัดการเหตุการณ์ที่แตกต่าง: ลายเซ็นเหตุการณ์ใน. NET - การใช้ 'ผู้ส่ง' ที่พิมพ์ได้ดีหรือไม่ . เป้าหมายที่นี่ไม่ได้ที่จะเอาผู้ส่ง แต่จะทำให้มันพิมพ์แข็งแกร่งทั่วไปว่าแทนการพิมพ์ที่ไม่ค่อยเป็นTSender System.Objectมันใช้งานได้ดีมาก อย่างไรก็ตามหนึ่งจะสูญเสียการสนับสนุน IntelliSense เมื่อคุณทำเช่นนี้จึงมีการแลกเปลี่ยนโชคร้าย

โดยรวมแล้วฉันจะใช้รูปแบบมาตรฐาน แต่น่าสนใจที่จะคิดวิธีที่ดีกว่านี้


ขอบคุณที่ชี้นำฉันไปยังคำถาม SO ของคุณ มันน่าสนใจสุด ๆ. ฉันยังไม่เข้าใจว่าทำไมจึงเป็นเรื่องสำคัญที่ผู้ส่งจะต้องทำ เวลาส่วนใหญ่ฉันไม่สนใจผู้ส่ง มันเป็นเพียงกฎ MS โดยพลการหรือไม่?
Matt Ellen

ไม่แน่นอนคุณสามารถประกาศผู้รับมอบสิทธิ์ตามที่คุณต้องการ มันเป็นนโยบายของ. NET ที่จะรวมผู้ส่งเสมอและมันก็ไม่ใช่ความคิดที่เลวร้าย
Neil

@ Neil: ฉันเข้าใจว่ามันมีประโยชน์บางครั้ง แต่ฉันไม่ได้รับนโยบายของการทำมันเสมอ - โดยเฉพาะอย่างยิ่งเมื่อ MS แนะนำให้ทำกิจกรรมตามที่ควร สิ่งหนึ่งที่ฉันชอบเกี่ยวกับเหตุการณ์คือความสามารถในการแยกชั้นเรียน ถ้าฉันรวมวัตถุแล้วมันก็กลับมารวมกันอีกครั้ง ถ้ามันเป็นเพียงสิ่งที่สอดคล้องกับ CLS ฉันก็สามารถอยู่กับมันได้
Matt Ellen

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

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