2008-12-21 8 views
9

सी # 3 में लैम्ब्डा सिंटैक्स इसे एक-लाइनर अज्ञात तरीकों को बनाने में वास्तव में सुविधाजनक बनाता है। वे शब्दकोष अज्ञात प्रतिनिधि वाक्यविन्यास पर एक निश्चित सुधार हैं जो सी # 2 ने हमें दिया है। हालांकि, लैम्ब्डा की सुविधा उन जगहों पर उनका उपयोग करने का एक प्रलोभन लाती है जहां हमें आवश्यक रूप से कार्यात्मक प्रोग्रामिंग अर्थशास्त्र की आवश्यकता नहीं होती है।घटना हैंडलरों के लिए Lambdas?

उदाहरण के लिए, मैं अक्सर लगता है कि मेरी ईवेंट हैंडलर्स कर रहे हैं (या कम से कम के रूप में शुरू ) सरल एक liners कि एक राज्य मान सेट एक और समारोह, या कॉल करें, या किसी अन्य वस्तु, आदि पर एक गुण सेट इनके लिए, क्या मुझे अपनी कक्षा को अभी तक एक और सरल कार्य के साथ अव्यवस्थित करना चाहिए, या क्या मुझे अपने कन्स्ट्रक्टर में घटना में लैम्बडा चाहिए?

इस परिदृश्य में lambdas के लिए कुछ स्पष्ट नुकसान कर रहे हैं:

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

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

हालांकि, दो अन्य चीजें हैं, जो मुझे लगता है कि शायद इतना स्पष्ट नहीं है, लेकिन संभवतः अधिक समस्याग्रस्त है।

  • प्रत्येक लैम्ब्डा समारोह इसके युक्त गुंजाइश पर एक बंद रूपों। इसका मतलब यह हो सकता है कि कन्स्ट्रक्टर में पहले बनाई गई अस्थायी वस्तुएं उन संदर्भों को बनाए रखने के बंद होने के कारण ज़्यादा ज़िंदा रहती हैं। अब उम्मीद है कि कंपाइलर लैम्बडा का उपयोग नहीं करने वाले बंद होने से वस्तुओं को बाहर करने के लिए पर्याप्त स्मार्ट है, लेकिन मुझे यकीन नहीं है। क्या कोई जानता है?

    सौभाग्य से, यह हमेशा एक मुद्दा नहीं है, क्योंकि मैं अक्सर अपने रचनाकारों में अस्थायी वस्तुओं को नहीं बनाता। मैं एक परिदृश्य की कल्पना कर सकता हूं जहां मैंने किया था, और जहां मैं इसे आसानी से लैम्ब्डा के बाहर नहीं छोड़ सका।

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

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

उत्तर

2

प्रत्येक लैम्ब्डा फ़ंक्शन इसके दायरे में बंद हो जाता है। इसका मतलब यह हो सकता है कि कन्स्ट्रक्टर में पहले बनाई गई अस्थायी वस्तुएं उन संदर्भों को बनाए रखने के बंद होने के कारण ज़्यादा ज़िंदा रहती हैं। अब उम्मीद है कि कंपाइलर लैम्बडा का उपयोग नहीं करने वाले बंद होने से वस्तुओं को बाहर करने के लिए पर्याप्त स्मार्ट है, लेकिन मुझे यकीन नहीं है। क्या कोई जानता है?

जो मैंने पढ़ा है, उससे सी # कंपाइलर या तो अज्ञात विधि या अज्ञात आंतरिक वर्ग उत्पन्न करता है, इस पर निर्भर करता है कि क्या इसमें शामिल क्षेत्र को बंद करने की आवश्यकता है या नहीं।

दूसरे शब्दों में, अगर आप अपने लैम्ब्डा के भीतर से युक्त गुंजाइश का उपयोग नहीं करते हैं, इसे बंद नहीं होगी।

बहरहाल, यह "अफवाह" का एक सा है, और मैं कोई है जो सी # संकलक के साथ अधिक जानकार उस पर में वजन है अच्छा लगेगा।

सब ने कहा, वर्ष सी # 2.0 गुमनाम प्रतिनिधि वाक्य रचना ऐसा ही किया था, और मैं लगभग हमेशा कम ईवेंट हैंडलर्स के लिए अनाम प्रतिनिधियों का उपयोग करता है।

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

+0

सी # संकलक दायरे में चर की ऐक्सेस देते हैं केवल यदि आप लैम्ब्डा * में इसका इस्तेमाल करते हैं, अन्यथा, यह एक समस्या नहीं है (यह लागू होता है अज्ञात तरीकों और भेड़ के बच्चे के लिए)। –

4

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

  1. ईवेंट पैरामीटर अनपैक करें।
  2. उपयुक्त पैरामीटर के साथ एक नामित विधि पर कॉल करें।

यह किया, मैं ईवेंट हैंडलर तरीके कि सफाई से अन्य प्रयोजनों के लिए उपयोग नहीं किया जा सकता है के साथ मेरी कक्षा नाम स्थान को अव्यवस्थित से बचा लिया है, और अपने आप की जरूरत है और कार्रवाई के तरीकों है कि मैं लागू करते हैं के प्रयोजनों के बारे में सोचने के लिए मजबूर किया, आमतौर पर क्लीनर कोड के परिणामस्वरूप।

+0

+1। यह मूल कोड में मेरे WNDProc में जो कुछ करता है उसके समान होता है। –

+0

हे, हाँ ... वह वहीं है जहां से मैं आ रहा हूं। – Shog9

1

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

कई मामलों में, घटना में है कि पता चला है बस हाथ में इस काम के लिए सही होने के लिए संदर्भ का एक छोटा पैकेज प्राप्त करने के लिए बनाया गया है।

मैं इसे एक रिफैक्टरिंग भावना में "अच्छी गंध" में से एक मानता हूं।

2

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

पहला लैम्डबा हार्ड कोडित मान का उपयोग करता था, दूसरे ने कन्स्ट्रक्टर में पैरामीटर का उपयोग किया था। पहला लैम्ब्डा कक्षा पर एक निजी स्थैतिक विधि के रूप में लागू किया गया था। दूसरा लैम्ब्डा एक वर्ग के रूप में लागू किया गया था जो समापन प्रदर्शन करता था।

तो आपकी धारणा है कि संकलक पर्याप्त स्मार्ट है, सही है।

+0

यह पुष्टि करता है कि मुझे नीचे क्या संदेह है। आईएल की जांच के लिए धन्यवाद। – FlySwat

+0

कोई समस्या नहीं, मुझे लगा कि यह इस तरह से काम करेगा लेकिन मेरी जिज्ञासा की पुष्टि करना चाहता था – JoshBerke

0

लैम्बडास, this question के बारे में मैंने हाल ही में पूछा कि स्वीकार्य उत्तर में ऑब्जेक्ट जीवनकाल पर प्रभावों के बारे में कुछ प्रासंगिक तथ्य हैं।

हाल ही में एक और दिलचस्प बात मैंने सीखा है कि सी # कंपाइलर एक ही गुंजाइश में कई बंदियों को समझता है जो इसे कैप्चर करता है और जीवित रहता है। दुख की बात है कि मुझे इसके लिए मूल स्रोत नहीं मिल रहा है। मैं जोड़ दूंगा कि अगर मैं इसे फिर से ठोकर खाऊंगा।

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

दूसरी तरफ, मैं समग्र रूप से थोड़ा अलग प्रकार की घटना तंत्र का उपयोग करता हूं, जो मुझे सी # भाषा सुविधा के लिए बेहतर लगता है: एक आईओएस-स्टाइल अधिसूचना केंद्र सी # में फिर से लिखा गया है, टाइप द्वारा की गई प्रेषण तालिका के साथ (व्युत्पन्न अधिसूचना) और कार्रवाई < अधिसूचना> मूल्यों के साथ। यह एकल लाइन "घटना" प्रकार परिभाषाओं की इजाजत दी समाप्त होता है, इसलिए जैसे: *

public class UserIsUnhappy : Notification { public int unhappiness; } 
संबंधित मुद्दे