2009-04-30 20 views
26

मेरे पास निम्नलिखित कोड है जो GUI को संग्रह में बदलाव का जवाब देने देता है।लैम्बडा अभिव्यक्ति का उपयोग करने वाली किसी ईवेंट से सदस्यता समाप्त कैसे करें?

myObservableCollection.CollectionChanged += ((sender, e) => UpdateMyUI()); 

सबसे पहले यह करने का यह एक अच्छा तरीका है?

दूसरा: इस घटना से सदस्यता समाप्त करने के लिए कोड क्या है? क्या यह वही है - = (और फिर पूर्ण अनाम विधि फिर से)?

+0

? डुप्लिकेट: http://stackoverflow.com/questions/183367/unsubscribe-anonymous-method-in-c – Richard

+0

देखें [यह] (http://stackoverflow.com/questions/183367/unsubscribe-anonymous- विधि -इन-ग)। –

+0

मैंने अपनी लैम्ब्डा अभिव्यक्ति को एक प्रतिनिधि (जैसा कि आपके लिंक में नहीं) में नहीं रखा है, इसलिए मेरे पास सदस्यता समाप्त करने का कोई संदर्भ नहीं है। –

उत्तर

20

यदि आपको किसी ईवेंट से सदस्यता समाप्त करने की आवश्यकता है, तो आपको एक त्वरित संदर्भ की आवश्यकता है। दुर्भाग्य से, इसका मतलब है कि आप उस विशेष वाक्यविन्यास का उपयोग नहीं कर सकते हैं।

+2

यदि "उस विशेष वाक्यविन्यास" से आपका मतलब है कि लैम्ब्डा बनाना और हैंडलर को एक पंक्ति में जोड़ना, तो हाँ। सरल समाधान सिर्फ लैम्ब्डा के संदर्भ को संग्रहीत कर रहा है। असल में, मुझे लगता है कि ओपी को सामान्य विधि का उपयोग करने की तलाश करनी चाहिए यदि उसे बार-बार संदर्भित करने की आवश्यकता है - यह कम से कम मेरे दिमाग में पठनीयता में सुधार करता है। – Noldorin

+0

इसे साफ़ करने के लिए धन्यवाद। –

+0

@ नोल्डोरिन येप, यही मेरा मतलब है "उस विशेष वाक्यविन्यास"। और मैं पूरी तरह से आपसे सहमत हूं। –

35

सबसे पहले ... हाँ यह करने का एक अच्छा तरीका है, यह साफ, छोटा रूप है और & पढ़ने में आसान है ... पाठ्यक्रम की चेतावनी "जब तक आप बाद में सदस्यता समाप्त नहीं करना चाहते हैं"।

मेरा मानना ​​है कि Jon Skeet से पहले इंगित किया गया है "विनिर्देश स्पष्ट रूप से व्यवहार की गारंटी नहीं देता है जब यह अनाम विधियों के साथ बनाए गए प्रतिनिधियों के समानता की बात आती है।"

इसलिए यदि आपको बाद में ईवेंट से सदस्यता समाप्त करने की आवश्यकता है, तो आप वास्तव में एक प्रतिनिधि उदाहरण बनाने के लिए सबसे अच्छा होगा ताकि आप बाद में संदर्भ पर लटका सकें।

var myDelegate = delegate(sender, e){UpdateMyUI()}; 

myObservableCollection.CollectionChanged += myDelegate; 

myObservableCollection.CollectionChanged -= myDelegate; 
+0

var myDelegate = प्रतिनिधि (प्रेषक, ई) {UpdateMyUI()}; संकलित नहीं करता है ... आपको प्रतिनिधि प्रकार निर्दिष्ट करने की आवश्यकता है। जॉन स्कीट अपने उदाहरण में एक्शन प्रतिनिधि का उपयोग करता है लेकिन इसमें केवल एक तर्क होता है। आपके उदाहरण में हमें किस प्रतिनिधि प्रकार का उपयोग करना चाहिए? –

+1

@RaduSimionescu: घटना के प्रकार के समान, जो इस उदाहरण में 'NotifyCollectionChangedEventHandler' होगा –

1

यह जाने के लिए एक ठीक तरह से है, जब तक myObservableCollection, 'यह' से अधिक समय रहने के लिए जा रहा है जिस स्थिति में आप एक स्मृति रिसाव लग सकती प्रतिनिधि जो पर्दे के पीछे बनाई गई है एक संरक्षण के रूप में, आपके 'इस' के संदर्भ में, जो इसे जीवित रखेगा। यदि आप बार-बार घटना बना रहे हैं और जो कुछ भी सुन रहे हैं उसे 'नष्ट' कर रहे हैं, तो आप पाएंगे कि उन्हें कचरा कलेक्टर द्वारा एकत्र नहीं किया जा रहा है।

यदि यह कोई समस्या है, तो आप उत्तर में सुझाए गए मार्ग पर जा सकते हैं, हैंडलर के संदर्भ को संरक्षित करते हुए, जिसे आपको पहले बनाना होगा।

एक और समाधान एक ईवेंट हैंडलर बनाने के लिए कमजोर संदर्भों का उपयोग करना है जो अन्य संदर्भ नहीं होने पर ग्राहक को एकत्रित करने की अनुमति देगा। मैंने this question and answer में इस समाधान की खोज की है।

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

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