2009-01-20 10 views

उत्तर

16

C++/CLI आप raisecustom event में संचालकों को ओवरराइड करने के ताकि आप null के लिए परीक्षण या कॉपी जब घटना को ऊपर उठाने की जरूरत नहीं है की अनुमति देता है। बेशक, अपने कस्टम raise अंदर आप अभी भी यह करने के लिए किया है।

उदाहरण के लिए, शुद्धता के लिए MSDN से अनुकूलित:

public delegate void f(int); 

public ref struct E { 
    f^_E; 
public: 
    void handler(int i) { 
     System::Console::WriteLine(i); 
    } 

    E() { 
     _E = nullptr; 
    } 

    event f^ Event { 
     void add(f^d) { 
     _E += d; 
     } 
     void remove(f^d) { 
     _E -= d; 
     } 
     void raise(int i) { 
     f^ tmp = _E; 
     if (tmp) { 
      tmp->Invoke(i); 
     } 
     } 
    } 

    static void Go() { 
     E^ pE = gcnew E; 
     pE->Event += gcnew f(pE, &E::handler); 
     pE->Event(17); 
    } 
}; 

int main() { 
    E::Go(); 
} 
28

यह पूरी कहानी नहीं है! आपको आमतौर पर सी ++/सीएलआई में नल इवेंट हैंडलर के बारे में चिंता करने की ज़रूरत नहीं है। इन चेक के लिए कोड आपके लिए जेनरेट किया गया है। निम्नलिखित छोटी सी ++/सीएलआई कक्षा पर विचार करें।

public ref class MyClass 
{ 
public: 
    event System::EventHandler^MyEvent; 
}; 

आप इस वर्ग के संकलन, और Reflector का उपयोग कर इसे एकत्रित न तो आपको नीचे दिए ग # कोड मिलता है।

public class MyClass 
{ 
    // Fields 
    private EventHandler <backing_store>MyEvent; 

    // Events 
    public event EventHandler MyEvent 
    { 
     [MethodImpl(MethodImplOptions.Synchronized)] add 
     { 
      this.<backing_store>MyEvent = (EventHandler) Delegate.Combine(this.<backing_store>MyEvent, value); 
     } 
     [MethodImpl(MethodImplOptions.Synchronized)] remove 
     { 
      this.<backing_store>MyEvent = (EventHandler) Delegate.Remove(this.<backing_store>MyEvent, value); 
     } 
     raise 
     { 
      EventHandler <tmp> = null; 
      <tmp> = this.<backing_store>MyEvent; 
      if (<tmp> != null) 
      { 
       <tmp>(value0, value1); 
      } 
     } 
    } 
} 

उठाए गए तरीके में सामान्य जांच की जा रही है। जब तक आप वास्तव में कस्टम व्यवहार चाहते हैं, आप ऊपर कक्षा में के रूप में अपने घटना की घोषणा, और एक अशक्त हैंडलर के डर के बिना यह बढ़ाने में परेशानी महसूस करना चाहिए।

+0

इस दृष्टिकोण के साथ मेरी समस्या यह है कि "raise" विधि निजी नहीं है (सी # में) और इंटेलिजेंस में दिखाती है। –

+1

@ फिलिप: तो एक कस्टम घटना के साथ जाएं और सामने 'निजी' रखें। –

7

अगर आपकी समस्या है कि उठाने निजी नहीं है है, तो स्पष्ट रूप से इसे लागू की तरह डॉक्स कहते हैं:

http://msdn.microsoft.com/en-us/library/5f3csfsa.aspx

सारांश में:

तुम सिर्फ का उपयोग करते हैं घटना कीवर्ड, आप एक "तुच्छ" घटना बनाएँ। संकलक जोड़ने/आप के लिए/उठाने और प्रतिनिधि सदस्य को निकालने उत्पन्न करता है। उत्पन्न उठाने समारोह (के रूप में डॉक्स कहते हैं) nullptr के लिए जाँच करता है। तुच्छ घटनाओं यहाँ प्रलेखित रहे हैं:

http://msdn.microsoft.com/en-us/library/4b612y2s.aspx

आप "अधिक नियंत्रण" चाहते हैं, उदाहरण के उठाने निजी बनाने के लिए के लिए है, तो आप के रूप में लिंक में दिखाया गया है स्पष्ट रूप से सदस्यों को लागू करने की है। आपको प्रतिनिधि प्रकार के लिए डेटा सदस्य स्पष्ट रूप से घोषित करना होगा। तो फिर तुम घटना से संबंधित सदस्यों की घोषणा करने के लिए Microsoft उदाहरण के रूप में घटना कीवर्ड का उपयोग करें:

// event keyword introduces the scope wherein I'm defining the required methods 
// "f" is my delegate type 
// "Event" is the unrealistic name of the event itself 
event f^ Event 
{ 
     // add is public (because the event block is public) 
     // "_E" is the private delegate data member of type "f" 
     void add(f^d) { _E += d; } 

    // making remove private 
    private: 
     void remove(f^d) { _E -= d; } 

    // making raise protected 
    protected: 
     void raise(int i) 
     { 
     // check for nullptr 
     if (_E) 
     { 
      _E->Invoke(i); 
     } 
     } 
}// end event block 

Wordy, लेकिन वहाँ यह है।

-reilly