2010-06-12 16 views
76

मुझे समझ में नहीं आता है कि घटनाओं को परिभाषित करते समय हमें "ईवेंट" कीवर्ड की आवश्यकता क्यों होती है, जब हम प्रतिनिधियों का उपयोग करके "ईवेंट" कीवर्ड का उपयोग किए बिना एक ही चीज़ कर सकते हैं।घटनाओं को परिभाषित करते समय हमें "ईवेंट" कीवर्ड की आवश्यकता क्यों है?

उदा।

public delegate void CustomEventHandler(int a, string b); 
public event CustomEventHandler customEvent; 
customEvent += new CustomEventHandler(customEventHandler); 
customEvent(1,"a"); // Raising the event 

यहां अगर मैं दूसरी पंक्ति से "ईवेंट" कीवर्ड को हटा देता हूं, तो मैं प्रतिनिधि को आमंत्रित करके ईवेंट भी बढ़ा सकता हूं। क्या कोई मुझे बता सकता है कि इस घटना कीवर्ड की आवश्यकता क्यों है?

+0

ठीक है अगर आप ईवेंट कीवर्ड का उपयोग नहीं करते हैं जो क्लास ऑब्जेक्ट का उपयोग करके उस ईवेंट तक पहुंच सकता है तो इसे objClass.SelectedIndexChanged = null जैसा सेट करें। यह आपके अंतर्निहित कोड को दुर्घटनाग्रस्त कर देगा। ईवेंट कीवर्ड उपयोगकर्ता को + = का उपयोग करके प्रतिनिधि के समान कुछ असाइन करने के लिए लागू करता है। –

उत्तर

92

फील्ड-तरह की घटनाओं और प्रतिनिधि प्रकार ही लगते हैं लेकिन वास्तव में बहुत अलग हैं की सार्वजनिक क्षेत्रों।

एक घटना मौलिक रूप से एक संपत्ति की तरह है - यह जोड़ने/निकालने के तरीकों की एक जोड़ी है (संपत्ति के प्राप्त/सेट के बजाय)। जब आप एक फ़ील्ड जैसी घटना घोषित करते हैं (यानी जहां आप स्वयं को जोड़ने/निकालने के बिट्स निर्दिष्ट नहीं करते हैं) एक सार्वजनिक ईवेंट बनाया जाता है, और एक निजी बैकिंग फ़ील्ड। यह आपको ईवेंट को निजी रूप से बढ़ाने देता है, लेकिन सार्वजनिक सदस्यता की अनुमति देता है। एक सार्वजनिक प्रतिनिधि क्षेत्र के साथ, कोई भी अन्य लोगों के ईवेंट हैंडलर को हटा सकता है, घटना को स्वयं उठा सकता है, आदि - यह एक encapsulation आपदा है।

घटनाओं (और प्रतिनिधियों) पर अधिक के लिए मेरे article on this topic पढ़ें। (किसी बिंदु पर मुझे इसे सी # 4 के लिए अपडेट करने की आवश्यकता है, जो फ़ील्ड जैसी घटनाओं को बहुत कम करता है। इसके बारे में अभी भी सही है।)

+4

यह एमएसडीएन के आधिकारिक एक-पंक्ति स्पष्टीकरण से हजार गुना बेहतर है: 'ईवेंट कीवर्ड का उपयोग प्रकाशक वर्ग में एक ईवेंट घोषित करने के लिए किया जाता है।' – cowlinator

5

यह आंशिक रूप से आवश्यक है क्योंकि यदि आप event कीवर्ड को छोड़ देते हैं, तो यह encapsulation को तोड़ देता है। यदि यह सिर्फ एक सार्वजनिक मल्टीकास्ट प्रतिनिधि है, तो कोई भी इसे आमंत्रित कर सकता है, इसे शून्य या उसके साथ छेड़छाड़ कर सकता है। यदि MailNotifier नामक एक वर्ग मौजूद है और इसमें MailReceived नामक एक ईवेंट है, तो mailNotifier.MailReceived() पर कॉल करके अन्य घटनाओं को उस घटना को आग लगाने में सक्षम होने का कोई अर्थ नहीं है;

दूसरी तरफ, आप इसे परिभाषित करने वाले प्रकार से 'फील्ड जैसे' घटनाओं के साथ केवल मध्यस्थता और आह्वान कर सकते हैं।

यदि आप अपने घटना मंगलाचरण को निजी रखना चाहते थे, वहाँ आप कुछ इस तरह कर रही है को रोकने के लिए कुछ भी नहीं है:

public class MyClassWithNonFieldLikeEvent 
{ 
    private CustomEventHandler m_delegate; 

    public void Subscribe(CustomEventHandler handler) 
    { 
     m_delegate += handler;   
    } 

    public void Unsubscribe(CustomEventHandler handler) 
    {   
     m_delegate -= handler; 
    } 

    private void DoSomethingThatRaisesEvent() 
    { 
     m_delegate.Invoke(...); 
    }  
} 

... लेकिन है कि बस के लिए कोड की एक पूरी लोड है (कम या ज्यादा) कर क्या क्षेत्र जैसी घटनाएं हमें पहले ही देती हैं।

+0

डिजाइनरों जैसे उपयोगों के लिए यह भी कठिन होगा ... आप मूल रूप से सार्वजनिक मेटाडेटा कह रहे हैं कि "यह एक घटना है" के बजाय विधियों के लिए नामकरण सम्मेलनों पर निर्भर रहना होगा। –

3

घटनाओं के प्रतिनिधियों के मुकाबले अलग-अलग फायदे हैं। घटनाओं को फ़ील्ड के विपरीत इंटरफ़ेस में परिभाषित किया जा सकता है, कोड में अमूर्तता जोड़ना और इससे भी महत्वपूर्ण बात यह है कि ईवेंट को केवल परिभाषित कक्षा के अंदर से ही बुलाया जा सकता है। आपके मामले में, कोई भी घटना को कॉल कर सकता है, संभवतः आपके कोड को नष्ट कर सकता है।

this blog post अधिक जानकारी के लिए देखें।

+2

आपको वास्तव में घटनाओं और * प्रतिनिधियों की तुलना नहीं करनी चाहिए * - एक प्रतिनिधि प्रकार * के साथ घटनाओं और * सार्वजनिक क्षेत्रों की तुलना करें। और नहीं, ढांचे * को उस हस्ताक्षर के लिए घटनाओं की आवश्यकता नहीं है। आप अपनी पसंद के किसी भी प्रतिनिधि प्रकार की एक घटना बना सकते हैं। –

+0

बहुत बहुत धन्यवाद। यह किताबों से स्पष्ट नहीं था। – teenup

+0

धन्यवाद जोन, तय। – Femaref

16

घटना कीवर्ड 3 अलग अलग बातें करता है:

  1. आप भले ही आप इंटरफेस में नियमित रूप से क्षेत्रों को परिभाषित नहीं कर सकते, एक अंतरफलक में किसी घटना को परिभाषित कर सकते हैं।
  2. यह = और () ऑपरेटरों (असाइनमेंट और आमंत्रण) की दृश्यता को निजी रूप से बदलता है, ताकि केवल युक्त वर्ग ईवेंट को आमंत्रित कर सके या इसमें मौजूद सभी विधियों को ओवरराइड कर सके। -= और += ऑपरेटरों को अभी भी परिभाषित कक्षा के बाहर से किसी ईवेंट पर बुलाया जा सकता है (वे ईवेंट के बगल में आपके द्वारा लिखे गए एक्सेस संशोधक को प्राप्त करते हैं)।
  3. आप -= और += ईवेंट पर व्यवहार करने के तरीके को ओवरराइड भी कर सकते हैं।
+0

जांचें http://pastebin.com/TMpib9ux मैंने कुछ उदाहरण प्रदान किया है। :) –

+0

आपकी स्पष्टीकरण को स्पष्ट करें – lucasasecas

16

अन्य उत्तरों ठीक हैं; मैं बस इसके बारे में सोचने के लिए कुछ और जोड़ना चाहता हूं।

आपका प्रश्न है "जब हमारे पास प्रतिनिधि प्रकार के क्षेत्र होते हैं तो हमें घटनाओं की आवश्यकता क्यों होती है?" मैं उस प्रश्न का विस्तार करूंगा: यदि आपके पास प्रतिनिधि प्रकार के क्षेत्र हैं तो आपको विधियों, गुणों, घटनाओं, उदाहरण कन्स्ट्रक्टर या फ़ाइनलाइज़र की आवश्यकता क्यों है? आपको कुछ भी फ़ील्ड के अलावा अन्य मूल्यों और प्रतिनिधियों को फ़ील्ड के अलावा क्यों चाहिए? क्यों न केवल

class C 
{ 
    private int z; 
    public readonly Func<int, int> M = (int x)=>{ return x+z; } 
    // ... and so on 
} 

?

आप विधियों, गुणों या घटनाओं की आवश्यकता नहीं है। हम आपको वह सामान देते हैं क्योंकि विधि, संपत्ति और घटना डिजाइन पैटर्न महत्वपूर्ण और उपयोगी हैं, और भाषा में उन्हें लागू करने के लिए एक मानक, दस्तावेज, स्पष्ट तरीका होने के लायक हैं।

+1

वाह! यह याद दिलाता है कि मुझे सी # क्यों पसंद है! मैंने जिन भाषाओं के साथ काम किया है, उनमें से कॉम्पैक्टनेस, लचीलापन और पठनीय अर्थशास्त्र का सही संतुलन है। एकमात्र तुलनीय भाषा ऑब्जेक्ट पास्कल है। –

+0

ऐसा नहीं है कि वह क्या पूछ रहा था .. उसने एक उचित सवाल पूछा, हमें घटना कीवर्ड की आवश्यकता क्यों है, यानी यह कुछ भी करता है .. यह कितना अंतर करता है, यह उपयोगी कब होगा। और आपका प्रश्न यह समझाता है कि हमें विधियों और गुणों की आवश्यकता क्यों होगी, इसलिए हमें वस्तुओं की आवश्यकता क्यों है, क्यों ओओपी, क्यों विधियां तो प्रक्रियाएं क्यों न केवल अनिवार्य प्रोग्रामिंग .. और आप कहते हैं "क्योंकि यह उपयोगी है"। प्रत्यक्ष रूप से। वह विशेष रूप से पूछ रहा था, क्यों नहीं विधियां उपयोगी हैं, क्यों ओओपी उपयोगी नहीं है। और सिर्फ यह कहकर कि ईवेंट कीवर्ड उपयोगी है, यह क्यों कहने के बिना कट नहीं करता है। – barlop

+0

@barlop: ठीक है, अगर आप इसे पसंद नहीं करते हैं तो आपको इस सात साल के प्रश्न के लिए बेहतर उत्तर देने के लिए स्वतंत्र महसूस करें। इस तरह पूरी साइट बेहतर हो जाती है। –

संबंधित मुद्दे