2010-08-31 19 views
5

मैंने कुछ लोगों को कॉलबैक/घटनाओं के तरीकों को सौंपने पर झुकाव देखा है और फिर कभी-कभी उन्हें केवल लैम्ब्डा सौंपते हैं।विधि सदस्यता बनाम लैम्ब्डा प्रतिनिधि सदस्यता - कौन और क्यों?

किसी को भी दोनों के बीच कोई अंतर से बात कर सकते हैं? मैंने मूल रूप से उन्हें एक जैसा माना होगा, लेकिन मैंने जो असंगतता देखी है, वह कभी-कभी मुझे आश्चर्यचकित कर देता है यदि कोई ऐसा मामला है जहां कोई दूसरे पर बेहतर हो? जाहिर है अगर कोड की बहुत बड़ी मात्रा है तो यह स्पॉट लैम्ब्डा पर नहीं होना चाहिए, लेकिन अन्यथा ..

क्या आप सभी दोनों के बीच किसी भी अंतर को रेखांकित कर सकते हैं, और नियमों को रेखांकित करते हैं जो आप बीच में चुनने के लिए उपयोग करते हैं दोनों जब दोनों उपलब्ध हैं?

उत्तर

7

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

m_button.Click += OnButtonClick; 
... 
m_button.Click -= OnButtonClick; 

लैम्बडास के साथ यह सरल नहीं है। आप लैम्ब्डा अभिव्यक्ति दूर की दुकान चाहिए और घटना

m_button.Click += delegate { Console.Write("here"); } 
... 
// Fail 
m_button.Click -= delegate { Console.Write("here"); } 

EventHandler del = delegate { Console.Write("here"); } 
m_button.Click += del; 
... 
m_button.Click -= del; 

यह वास्तव में लैम्ब्डा भाव के उपयोग की सुविधा की राह में बाधक से unsbuscribe को बाद में प्रयोग की जाने वाली।

+0

मुझे + = (प्रेषक, ई) => {} की आदत में मिला है और कभी इसके बारे में सोचा नहीं है, लेकिन अगर मैं चाहता था तो मैं उस विशिष्ट श्रोता को नहीं हटा सका, अच्छा बिंदु .. –

+0

@ जिमी, अक्सर बार आपको इसकी आवश्यकता नहीं है और यह बिंदु अप्रासंगिक हो जाता है। लेकिन यह आपके द्वारा किए जाने वाले समय पर परेशान है। – JaredPar

2

लैम्बडास (सी # समेत) में अधिकांश भाषाओं में, एक विधि के अंदर एक लैम्ब्डा बनाने से बंद हो जाता है - यानी, घोषित विधि के अंदर स्थानीय चर लैंबडा को दिखाई देंगे। यह सबसे बड़ा अंतर है जिसके बारे में मुझे पता है।

कि से

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

1

एक लैम्ब्डा प्रयोग करने के लिए सबसे बड़ा कारण निष्पादन में देरी की है, यानी आप आपरेशनों, जो आप चाहते को परिभाषित है, लेकिन आप बाद में जब तक पैरामीटर नहीं होगा। आप आम तौर पर घटनाओं और कॉलबैक के लिए लैम्बडा का उपयोग नहीं करते हैं; आप अज्ञात तरीकों का उपयोग करते हैं।

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

सामान्य तौर पर, मैं कॉलबैक और अनाम तरीकों की तुलना में अधिक घटनाओं के लिए वास्तविक तरीकों का उपयोग; जिन घटनाओं को मैं संभालना चाहता हूं वे ऑब्जेक्ट के जीवनकाल से बंधे हैं, विधि के जीवनकाल से नहीं, और मुझे लगता है कि कोड में यह स्पष्ट है कि कॉलबैक स्पष्ट रूप से उस कार्य को बाहरी रूप से परिभाषित करता है जो उन्हें हुक करता है। उनमें से कुछ व्यक्तिगत वरीयता है।

+1

लैम्बदास शब्द की सामान्य समझ में निष्पादित नहीं हैं। वे सिर्फ प्रतिनिधि हैं और सामान्य प्रतिनिधि व्यवहार करते हैं। विलंबित निष्पादन आमतौर पर LINQ प्रश्नों का वर्णन करने के लिए प्रयोग किया जाता है जिनमें लैम्बडास की तुलना में विभिन्न अर्थशास्त्र होते हैं। – JaredPar

+0

आप सही, अच्छे बिंदु हैं। LINQ वह जगह है जहां मैं मुख्य रूप से लैम्ब्डा का उपयोग करता हूं, वहां मेरे सिर में भेद धुंधला हो गया –

0

ज्यादातर मामलों में, वहाँ थोड़ा व्यावहारिक अंतर है। उपयोग करने के लिए कौन सा मुख्य रूप से व्यक्तिगत वरीयता का मामला है (यानी आप कोड को देखें देखें)।

  1. the accepted answer में बताया गया है, सदस्यता समाप्ति के एक गुमनाम विधि एक नामित विधि सदस्यता समाप्ति से अधिक जटिल है के रूप में: कुछ मामलों में, वहाँ एक दूसरे के ऊपर करने के लिए पसंद करते हैं कुछ व्यावहारिक कारण हैं। किसी नाम के बिना, रनटाइम पर बनाए गए प्रतिनिधि उदाहरण को छोड़कर अनाम विधि को संदर्भित करने का कोई तरीका नहीं है जहां अनाम विधि घोषित की जाती है। नामित विधि का उपयोग करके, प्रतिनिधि को मूल प्रतिनिधि (या उसके समतुल्य) के संदर्भ को बनाए रखने के बिना सदस्यता रद्द की जा सकती है।
  2. दूसरी तरफ, लैम्ब्डा अभिव्यक्ति को प्राथमिकता देने का एक कारण यह है कि घटना के लिए हैंडलर नामित विधि के लिए एक कार्यान्वयन विवरण है जिसमें लैम्ब्डा/अज्ञात विधि घोषित की जाती है। यह इस तरह के कार्यान्वयन विवरण को निजी और स्थानीय तरीके से विधि में रखने में मदद कर सकता है जहां उनका उपयोग किया जाता है।
  3. एक अन्य कारण लैम्बडा अभिव्यक्ति का उपयोग कर सकता है यदि प्रतिनिधि प्रकार को "अनुकूलित" करने की आवश्यकता है। अर्थात। आप ईवेंट को संभालने के लिए नामित विधि को कॉल करना चाहते हैं, लेकिन उस विधि के अनुसार उस विधि की तुलना में एक अलग हस्ताक्षर है। यह वह मामला हो सकता है जहां आप विभिन्न घटनाओं या अन्य परिस्थितियों के लिए विधि का पुन: उपयोग करना चाहते हैं, जहां ईवेंट के कुछ पैरामीटर लागू नहीं हो सकते हैं। एक और मामला हो सकता है कि आप एक नया पैरामीटर एक मूल्य पेश करना चाहते हैं जिसके लिए ईवेंट प्रदान नहीं किया जा सकता है (उदाहरण के लिए ऑब्जेक्ट्स के संग्रह के लिए एक इंडेक्स जिसमें सभी एक ही ईवेंट है जिसे आप सब्सक्राइब करना चाहते हैं)।

एक विशेष मामला है जो कभी-कभी आ सकता है, जो कि नामित विधि का उपयोग करना है या किसी अज्ञात विधि का उपयोग करना है, जिसे उस नामित विधि को कॉल किया गया है। यह ध्यान रखना महत्वपूर्ण है कि, किसी अन्य नाम को चुनने के लिए अन्य व्यावहारिक कारणों की अनुपस्थिति में, नामित विधि का उपयोग करना इस विशेष मामले में है, क्योंकि यह आमंत्रण से एक विधि कॉल को हटा देता है। व्यावहारिक रूप से, आप शायद कभी अंतर नहीं देखेंगे, लेकिन यह सिर्फ ऊपर की ओर है इसलिए यदि कोई विशिष्ट, व्यावहारिक कारण नहीं है, तो शायद इसे टालना चाहिए, यानी नामित विधि की सदस्यता लें।

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