मैं सोच रहा था C++/CLI से घटनाओं को ऊपर उठाने का उचित तरीके से क्या। सी # एक एस hould first make a copy of the handler, check if it's not null, and then call it में। क्या सी ++/सीएलआई के लिए एक समान अभ्यास है?उचित तरीका है?
उत्तर
C++/CLI आप raise
custom 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();
}
यह पूरी कहानी नहीं है! आपको आमतौर पर सी ++/सीएलआई में नल इवेंट हैंडलर के बारे में चिंता करने की ज़रूरत नहीं है। इन चेक के लिए कोड आपके लिए जेनरेट किया गया है। निम्नलिखित छोटी सी ++/सीएलआई कक्षा पर विचार करें।
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);
}
}
}
}
उठाए गए तरीके में सामान्य जांच की जा रही है। जब तक आप वास्तव में कस्टम व्यवहार चाहते हैं, आप ऊपर कक्षा में के रूप में अपने घटना की घोषणा, और एक अशक्त हैंडलर के डर के बिना यह बढ़ाने में परेशानी महसूस करना चाहिए।
अगर आपकी समस्या है कि उठाने निजी नहीं है है, तो स्पष्ट रूप से इसे लागू की तरह डॉक्स कहते हैं:
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।
इस दृष्टिकोण के साथ मेरी समस्या यह है कि "raise" विधि निजी नहीं है (सी # में) और इंटेलिजेंस में दिखाती है। –
@ फिलिप: तो एक कस्टम घटना के साथ जाएं और सामने 'निजी' रखें। –