2010-08-23 16 views
6

मुझे कुछ मदद की ज़रूरत है कि मैं एक नया कस्टम इवेंट कैसे बना सकता हूं। मैं here से पढ़ें ...सी #: इवेंट सिंटैक्स समझना

public delegate void ChangingHandler (object sender, CarArgs ca); 
public event ChangingHandler Change; 
... 
private void car_Change(object sender, CarArgs ca) { 
    MessageBox.Show(ca.Message()); 
} 
... 
car.Change+=new Car.ChangingHandler(car_Change); // add event handler 
... 
Change(this,ca); // call event 

1st, मैं सच में प्रतिनिधि हिस्सा मिलता है न। एक सामान्य चर declartion,

protected string str1; 

लेकिन यहाँ में मैं अतिरिक्त (ChangingHandler) है। मैं इसका कैसे समझूं? मुझे पता है कि चेंजिंग हैंडलर की तरह कुछ इस घटना को संभालने के लिए इस्तेमाल किया जाएगा, लेकिन यह मुझे छोड़ देता है।

public event ChangingHandler Change 

तो

car.Change+=new Car.ChangingHandler(car_Change) 

मुझे नहीं वास्तव में वाक्य रचना new Car.ChangingHandler(car_Change) मिलता है।

उत्तर

17

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

इस तरह कोई व्यक्ति ईवेंट को अपनी विधि में पॉइंटर दे सकता है, जिसे "ईवेंट हैंडलर" के रूप में जाना जाता है। जब भी घटना के मालिक को लगता है कि यह उचित है तो ईवेंट इस विधि को कॉल करेगा।

प्रतिनिधि, इस अर्थ में, यह कहने से कुछ और नहीं है कि घटना किस प्रकार की विधि स्वीकार करेगी। आपके पास ईवेंट को एक ऐसा तरीका नहीं दे सकता है जिसमें कोई तर्क न हो और 5 जो लेता है, उसे पता नहीं होगा कि उन्हें कैसे कॉल किया जाए। तो प्रतिनिधि घटना और घटना हैंडलर के बीच अनुबंध है, जो उन्हें बताता है कि विधि हस्ताक्षर के लिए क्या अपेक्षा की जानी चाहिए।

आपके मामले में, यह शायद सिर्फ EventHandler<T> है, जो एक आपके घटना प्रतिनिधि के लिए प्रपत्र void EventHandler<T>(object sender, T eventArgs) के प्रतिनिधि में बनाया गया है, इस तरह का उपयोग करने के लिए बेहतर है:

public event EventHandler<CarArgs> Change; 

सी # वास्तव में समारोह संकेत नहीं है कच्चे अर्थ में। प्रतिनिधि इसके बजाय इसे संभालते हैं। वे दृढ़ता से टाइप, ऑब्जेक्ट उन्मुख फ़ंक्शन पॉइंटर्स की तरह हैं। जब आप

car.Change+=new Car.ChangingHandler(car_Change); 

आप घटना एक नया प्रतिनिधि (समारोह सूचक) है कि आपके car_Change ईवेंट हैंडलर के लिए अंक, अपने car_Change विधि कॉल करने के जब यह तैयार है घटना बता दे रहे हैं कहते हैं। प्रतिनिधि (new ChangeHandler(...) बस car_Change विधि के लिए सूचक गिर्द घूमती है।

+1

नोट, आपको स्पष्ट रूप से प्रतिनिधि उदाहरण बनाने की आवश्यकता नहीं है। आप 'कार' कर सकते हैं। बदलें + = car_Change; '(यह सुंदर बेवकूफ है) – bruceboughton

3

के रूप में भी यह पता चला है कि आप car.Change += new Car.ChangingHandler(car_Change); sytax की जरूरत नहीं है के रूप में यह बहुत सहज ज्ञान युक्त के रूप में आप ने बताया नहीं है।

आप बस लिख सकता है car.Change += car_Change; संभालने car_Change सही विधि हस्ताक्षर हैं।

11

एक घटना एक निश्चित हस्ताक्षर हैं। यह हस्ताक्षर को परिभाषित करता है क्या एक श्रोता क्या मापदंडों और क्या वापसी प्रकार यह होनी चाहिए। यह अनुबंध एक को परिभाषित करते हुए व्यक्त किया जाता है के मामले में की तरह लग रहे चाहिए प्रतिनिधि।अपने कोड नमूना से:

public delegate void ChangingHandler (object sender, CarArgs ca); 

यहाँ हम एक object और एक CarArgs पैरामीटर के रूप में, और एक void वापसी प्रकार के साथ लेने के तरीकों के लिए एक प्रतिनिधि को परिभाषित किया है।

अगला हम जैसे घटना की घोषणा:

public event ChangingHandler Change; 

तो, हम Change नाम का एक ईवेंट है, और घटना के श्रोताओं ChangingHandler प्रतिनिधि के रूप में एक ही हस्ताक्षर होना आवश्यक है।

फिर हम एक श्रोता विधि की जरूरत है:

private void car_Change(object sender, CarArgs ca) { 
    MessageBox.Show(ca.Message()); 
} 

यहाँ हम देख सकते हैं कि यह कैसे ChangingHandler प्रतिनिधि के रूप में एक ही हस्ताक्षर हैं।

अंत में हम इस घटना के लिए listner संलग्न कर सकते हैं:

car.Change+=new Car.ChangingHandler(car_Change) 

तो, हम एक नया ChangingHandler उदाहरण है कि car_Change विधि को संदर्भित करता बनाते हैं, और इस घटना के लिए प्रतिनिधि उदाहरण गुजरती हैं।

सब कहा, मैं बजाय अपने खुद के बनाने के पूर्वनिर्धारित EventHandler<T> प्रतिनिधि का उपयोग करने की सिफारिश करेंगे:

public event EventHandler<CarArgs> Change; 
0

एक इस बारे में सोच के कच्चे रास्ते: प्रतिनिधि प्रकार परिभाषित करता है कि "होगा समारोह के आकार" अपने कार्यक्रम का आधार बनें। तो ChangingHandler फ़ंक्शन जैसा दिखना चाहिए।

आगे बढ़ते हुए, एक प्रतिनिधि उदाहरण फ़ंक्शन पॉइंटर की तरह होता है। उन शर्तों में इसके बारे में सोचो।

public event ChangingHandler ChangeChange नामक फ़ंक्शन पॉइंटर को परिभाषित करता है जो आकार ChangingHandler आकार के कार्यों को इंगित करेगा।

लेकिन वर्तमान में, यह फ़ंक्शन पॉइंटर कुछ भी इंगित नहीं कर रहा है। यही वह जगह है जहां car.Change += new Car.ChangingHandler(car_Change) बिट आता है।

इसे दो चरणों में लें। प्रतिनिधि सामान्य कार्य पॉइंटर्स नहीं हैं; वे वास्तव में फ़ंक्शन पॉइंटर स्टैक की तरह अधिक हैं, आप एक प्रतिनिधि को कई फ़ंक्शन कर सकते हैं। यही कारण है कि आप लोगों को एक घटना में "सदस्यता लेने" के बारे में अधिक सामान्य बात करते हैं; घटना में अपना फ़ंक्शन जोड़ना मतलब होगा कि ईवेंट को आग लगने पर इसे कॉल किया जाएगा। आप + = ऑपरेटर के साथ प्रतिनिधि "स्टैक" में अपना फ़ंक्शन जोड़ते हैं।

आप सीधे एक प्रतिनिधि को फ़ंक्शन नहीं जोड़ सकते हैं, इसे प्रतिनिधि के संदर्भ में व्यक्त किया गया है। यह एक ही पंक्ति पर new ऑब्जेक्ट बनाने के लिए एक थ्रो तरीके से किया जाता है जो आप ईवेंट में अपना फ़ंक्शन जोड़ते हैं; हालांकि सी # 2.0 के बाद से मेरा मानना ​​है कि आप सीधे new वाक्यविन्यास के बिना कार्यों को जोड़ सकते हैं।

1

घटनाक्रम प्रतिनिधियों की अवधारणा पर आधारित हैं, एक प्रतिनिधि मूल रूप से एक विधि हस्ताक्षर परिभाषा है। बस इतना ही। एक इंटरफ़ेस की तरह आप विधि हस्ताक्षर कैसे परिभाषित करते हैं, लेकिन आप उन्हें लागू नहीं करते हैं, तो आप उस इंटरफ़ेस को प्राप्त करने वाले सभी वर्गों में ऐसा करते हैं।

एक प्रतिनिधि एक विधि हस्ताक्षर के लिए एक परिभाषा है, और जिसके लिए आप परिभाषित कर सकते हैं के रूप में कई विधि शरीर की आप की तरह, उदाहरण के लिए, इस प्रतिनिधि (विधि हस्ताक्षर परिभाषा) दिए गए हैं:

public delegate void ChangingHandler (object sender, CarArgs ca); 

आप परिभाषित कर सकते हैं इस प्रतिनिधि (विधि हस्ताक्षर परिभाषा) जैसे के साथ शरीर:

public void SomeMethodWhichCreatesADelegateBody() 
{ 
    ChangingHandler myChangingHandler = new ChangingHandler(
     delegate(object sender, EventArgs e) { /* the method body for myChangingHandler */ } 
    ); 
} 

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

अब घटनाओं को शरीर की एक सरणी के साथ एक प्रतिनिधि (विधि हस्ताक्षर परिभाषा) के रूप में कल्पना की जा सकती है जिसे घटना की सदस्यता लेने के रूप में प्रस्तुत किया जाता है, किसी ईवेंट में विधि निकाय की सदस्यता लेने के लिए वाक्यविन्यास += है और इसके लिए वाक्यविन्यास भी है एक घटनाओं सदस्यता जो -=

तो यहाँ इस कोड को एक ChangingHandler प्रतिनिधि के लिए शरीर की की सरणी (विधि हस्ताक्षर परिभाषा) को परिभाषित करता है से एक विधि शरीर को हटाने:

public event ChangingHandler Change; 

और तुम शरीर की (उन्हें जोड़ने सदस्यता ले सकते हैं सरणी) कॉलि द्वारा इस समूह के लिए एक विधि में एनजी:

public void SomeMethodWhichSubscribesADelegateBodyToAnEvent() 
{ 
    ChangingHandler myChangingHandler = new ChangingHandler(
     delegate(object sender, EventArgs e) { /* the method body for myChangingHandler */ } 
    ); 

    Change += myChangingHandler; 
} 

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

if (Change != null) // You wouldn't access an array without making sure it wasn't null, would you? 
{ 
    Change(this, new CarArgs()); // This executes every method body in it's array using the signature definition the delegate defined. 
    // The delegate simply exists so this code knows the method signature 
    // so it can know how to call those method body's for you. 
} 
संबंधित मुद्दे