2009-02-21 9 views
22

मुझे एक घटना के ग्राहकों को किसी अन्य ईवेंट में कॉपी करने की आवश्यकता है। क्या मुझे किसी ईवेंट के ग्राहक मिल सकते हैं (जैसे MyEvent [0] एक प्रतिनिधि को लौट रहा है)?मैं किसी ईवेंट के ग्राहक कैसे प्राप्त करूं?

यदि यह संभव नहीं है तो मैं सूची में प्रतिनिधियों को जोड़ने के लिए एड एक्सेसर का उपयोग करूंगा। क्या यह सबसे अच्छा समाधान होगा?

उत्तर

20

सी # घटनाओं/प्रतिनिधियों मल्टीकास्ट हैं, इसलिए प्रतिनिधि स्वयं एक सूची है। वर्ग के भीतर से, अलग-अलग कॉल प्राप्त करने के लिए, आप का उपयोग कर सकते हैं:

if(field != null) { // or the event-name for field-like events 
    // or your own event-type in place of EventHandler 
    foreach(EventHandler subscriber in field.GetInvocationList()) 
    { 
     // etc 
    } 
} 

हालांकि, एक बार में सभी आवंटित करने के लिए, बस का उपयोग + = या प्रत्यक्ष काम:

SomeType other = ... 
other.SomeEvent += localEvent; 
+0

इसे इंगित करने के लिए धन्यवाद। यह मेरे अपने कोड में घटनाओं के लिए सबसे अच्छा है। – weiqure

+0

इसके लिए बहुत बहुत धन्यवाद। बाइनरी सीरियलाइजेशन के माध्यम से ऑब्जेक्ट क्लोनिंग के लिए मुझे सब्स्क्राइब किए गए कार्यक्रमों का आनंद लेने के लिए एक अच्छा कामकाज की आवश्यकता नहीं थी, अन्यथा मुझे कई सौ वर्गों में आईसीएलनेबल को लागू करना होगा। – user1039513

3

अद्यतन (टिप्पणी करने वालों के लिए धन्यवाद): प्रतिनिधि प्रतिरक्षा का मतलब है कि क्लोनिंग एक असाइनमेंट पर कुछ भी हासिल नहीं करता है।

जब एक लिखते हैं:

myDelegate += AHandler 

एक पूरी तरह से नए प्रतिनिधि उदाहरण बनाया और myDelegate को सौंपा गया है।

इसलिए, नीचे दिया गया कोड क्लोन कॉल के बिना बिल्कुल वही काम करेगा।


मल्टीकास्टडिलेगेट (अंतर्निहित प्रकार) में क्लोन विधि है।

अंतर्निहित प्रतिनिधि को प्राप्त करने में सक्षम होने के लिए आपको सामान्य हेल्पर से बचने की आवश्यकता हो सकती है कि ईवेंट कीवर्ड उत्पन्न होता है, और चीजों को सीधे प्रबंधित करता है (कस्टम जोड़ें और एक्सेसर्स को हटाएं)।

इस दिखाने के लिए:

 
    class Program { 
     public delegate void MyDelegate(string name); 

     public event MyDelegate EventOne; 

     public void HandlerOne(string name) { 
      Console.WriteLine("This is handler one: {0}", name); 
     } 
     public void HandlerTwo(string name) { 
      Console.WriteLine("This is handler two: {0}", name); 
     } 
     public void HandlerThree(string name) { 
      Console.WriteLine("This is handler three: {0}", name); 
     } 

     public void Run() { 
      EventOne += HandlerOne; 
      EventOne += HandlerTwo; 
      Console.WriteLine("Before clone"); 
      EventOne("EventOne"); 

      
            
 
  
             MyDelegate eventTwo = (MyDelegate)EventOne.Clone();
            
  
      MyDelegate eventTwo = EventOne; 
      Console.WriteLine("After 
            
 
  
             clone
            
 copy"); 
      EventOne("EventOne"); 
      eventTwo("eventTwo"); 

      Console.WriteLine("Change event one to show it is different"); 
      EventOne += HandlerThree; 
      EventOne("EventOne"); 
      eventTwo("eventTwo"); 
     } 

     static void Main(string[] args) { 
      (new Program()).Run(); 
     } 
    } 
+0

क्लोन स्वयं अपेक्षाकृत महत्वहीन है - प्रतिनिधि अपरिवर्तनीय हैं, इसलिए आप प्रतिनिधि प्रतिनिधि की प्रतिलिपि बना सकते हैं। –

+0

जब तक नमूना में नहीं, तब आप मूल को संशोधित करना चाहते हैं या स्वतंत्र रूप से प्रतिलिपि बनाना चाहते हैं। – Richard

+0

रिचर्ड - नहीं, यह क्लोन() चरण के बिना ** समान रूप से ** काम करेगा। –

13

तो घटना एक अन्य वर्ग द्वारा प्रकाशित, आप नहीं कर सकते - कम से कम, मज़बूती से नहीं। जबकि हम अक्सर एक प्रतिनिधि चर के रूप में एक घटना के बारे में सोचते हैं, यह वास्तव में केवल एक जोड़ी है: जोड़ें और हटाएं (या सब्सक्राइब करें और सदस्यता समाप्त करें)।

यदि यह आपका स्वयं का कोड है जो ईवेंट प्रकाशित कर रहा है, तो यह आसान है - आप जो भी चाहें एक्सेसर्स को जोड़/हटा सकते हैं।

my article on events पर एक नज़र डालें और देखें कि क्या यह आपकी मदद करता है। यदि नहीं, तो कृपया आप जो करना चाहते हैं उसके बारे में अधिक जानकारी दें, निर्दिष्ट करें कि आप किस कोड के संशोधित करने में सक्षम हैं और जो आप नहीं हैं।

1

मामले में आप की जांच करने की जरूरत है बाहरी वर्ग के ग्राहक 'घटना:

EventHandler e = typeof(ExternalClass) 
    .GetField(nameof(ExternalClass.Event), BindingFlags.Instance | BindingFlags.NonPublic) 
    .GetValue(instanceOfExternalClass) as EventHandler; 
if (e != null) 
{ 
    Delegate[] subscribers = e.GetInvocationList(); 
} 
संबंधित मुद्दे