2010-08-20 25 views
17

मैं स्टैक ओवरफ़्लो पर एक प्रश्न का उत्तर पढ़ बनाम एक लैम्ब्डा अभिव्यक्ति का उपयोग करना है कि निम्नलिखित सुझाव कोड निहित LogAndEat के लिए लैम्ब्डा अभिव्यक्ति के रूप में (मेरे विचार में सरल और अधिक स्पष्ट) निजी विधि का विरोध करने के इस प्रकार है:एक निजी विधि

private void LogAndEat(Exception ex) 
{ 
    // Log Error and eat it 
} 

संपादित करें: जवाब के लिए धन्यवाद अब तक लेकिन सिर्फ मेरी बुनियादी सवाल restating थोड़ा और सीएल प्रारंभिक: कौन सा दृष्टिकोण बेहतर है/क्या आप इस उदाहरण में अनुशंसा करेंगे? एक लैम्ब्डा अभिव्यक्ति या एक निजी विधि?

उत्तर

1

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

एक लैम्ब्डा अभिव्यक्ति (ले) का उपयोग कर के पेशेवरों के लिए एक निजी विधि के बजाय:

  • एक ले तरीका है जिसमें यह इसलिए यदि यह उसके बाद ही है कि उस विधि से प्रयोग किया जाता है घोषित किया जाता है के दायरे वाला इरादा लैम्ब्डा अभिव्यक्ति द्वारा स्पष्ट किया गया है (भले ही ली के लिए एक प्रतिनिधि को पास करना संभव हो, फिर भी कोई भी विधि में एक LE घोषित करने के इरादे से बहस कर सकता है कि LE विधि को स्कॉप्ड किया गया है)। यही है, इसके अपेक्षित उपयोग के संदर्भ में स्पष्ट होना।
  • लैम्ब्डा अभिव्यक्ति बंद होने की तरह व्यवहार करती है ताकि वे जिस तरीके से घोषित किए गए तरीके से स्केल किए गए वेरिएबल्स तक पहुंच सकें। यह एक निजी विधि में कई पैरामीटर पारित करने से पहले साफ हो सकता है।
  • एक ली द्वारा कब्जा कर लिया गया चर अन्यथा एक निजी विधि के पैरामीटर होंगे और इसका उपयोग करी के रूप में अनुमति देने के लिए किया जा सकता है। एक निजी विधि के बजाय एक लैम्ब्डा अभिव्यक्ति का उपयोग करने का

विपक्ष:

  • ले चर का उपयोग कर सकते क्योंकि विधि है जिसमें वे शामिल हैं के दायरे वाला, उस में कोड को संशोधित करने के लिए संभव नहीं है डीबगिंग के दौरान कॉलिंग विधि।

रखरखाव का अधिक विषयपरक मुद्दा भी है और कोई तर्क दे सकता है कि अधिकांश डेवलपर्स द्वारा LE को एक निजी विधि के रूप में समझा नहीं जाता है और इस प्रकार कुछ हद तक कम रखरखाव योग्य होता है। कोई यह भी तर्क दे सकता है कि एक LE रखरखाव में सुधार करता है क्योंकि यह उस विधि में encapsulated है जिसमें इसे एक निजी विधि के विपरीत कहा जाता है जो पूरे वर्ग के लिए दृश्यमान है।

9

logAndEat द्वारा कैप्चर किए गए चर अन्यथा LogAndEat विधि के पैरामीटर होंगे। आप इसे करी का एक रूप मान सकते हैं।

+0

+1 हालांकि यह इस विशेष कोड नमूने में नहीं हो रहा है। हालांकि यह करने का एक अच्छा कारण है। –

+0

अपने सभी को दायरे के बारे में +1 करें –

+0

क्या यह वास्तव में करी का एक रूप है? – crypted

12

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

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

यह वास्तव में एकमात्र लाभ है जिसे मैं सोच सकता हूं - अपेक्षित उपयोग के संदर्भ में स्पष्ट होना।

+0

यद्यपि आप चाहते हैं कि * प्रतिनिधि * बाहर निकल सकते हैं। यदि कोई प्रतिनिधि उदाहरण पास हो जाता है तो आपको कोई बाधा नहीं है जो आपको घोषित विधि के बाहर कोड निष्पादित करने से रोकती है। –

+0

@ एरिक हाँ, आप हमेशा के लिए लैम्ब्डा वापस आ सकते हैं। ऐसा लगता है कि उदाहरण कोड ऐसा करने वाला नहीं था इसलिए मैंने उस संभावना को छूट दी। :) –

+0

तो क्या यह आपकी प्रतिक्रिया के जोर से मुकाबला करता है, या कोई तर्क दे सकता है (जैसा कि मुझे लगता है) कि अगर आप अभिव्यक्ति के * इच्छित * दायरे पर विचार करते हैं तो आपका उत्तर सही है, वास्तविक वास्तविक दायरे के विपरीत प्रतिनिधि उदाहरण पारित किया गया है? आपका जवाब मुझे समझ में आता है लेकिन इस तरह एक लैम्ब्डा अभिव्यक्ति का उपयोग करना मेरे लिए थोड़ा * मुश्किल * लगता है - इसमें यह गलत नहीं है, यह सिर्फ मामूली लाभ के लिए असामान्य तरीके से कुछ कर रहा है। –

0

IMO मैं छोटे-छोटे निजी कार्यों कि केवल अपने वर्गों के आसपास सोच एक और निजी विधि में किया जाता है मैं सिर्फ उन्हें बदसूरत लगता है पसंद नहीं है, यही कारण है कि मुझे लगता है कि नमूने में लैम्ब्डा प्रयोग करेंगे

मैं डॉन है ' टी सोचते हैं कि फ़ंक्शन

1

निजी वरीयता के लिए बहुत कुछ नीचे आता है, कोई भी नहीं कह सकता कि एक पूर्ण तरीका सही तरीका है या गलत तरीका है।

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

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

3

LogAndEat उस क्षेत्र के भीतर निजी फ़ील्ड को संदर्भित कर सकता है जहां इसे परिभाषित किया गया है। तो:

private bool caughtException; 

Action<Exception> logAndEat = ex => 
    { 
     caughtException = true; 
    }; 

try 
{ 
    // Call to a WebService 
} 
catch (SoapException ex) 
{ 
    logAndEat(ex); 
} 
catch (HttpException ex) 
{ 
    logAndEat(ex); 
} 
catch (WebException ex) 
{ 
    logAndEat(ex); 
} 

if (caughtException) 
{ 
    Console.Writeline("Ma, I caught an exception!"); 
} 

यह एक घिसे-पिटे उदाहरण है, लेकिन यह संभवतः एक निजी विधि के माध्यम से मानकों का एक गुच्छा गुजर की तुलना में बहुत tidier हो सकता है (!)।

+0

और कक्षा में सार्वजनिक क्षेत्रों को 'चर' भी कहा जाता है। किसी बिंदु को प्रभावी ढंग से संवाद करने के लिए भाषा का उपयोग न करने का कोई कारण नहीं है, जो इस मामले में पाठक को याद दिलाना था कि 'चर' आमतौर पर फ़ंक्शन के बाहर परिभाषित कोड द्वारा पहुंच योग्य नहीं होगा। – shannon

2

यह समझने के लिए कि लैम्बडा अभिव्यक्ति का उपयोग करना बेहतर है (जैसा कि मैंने original answer में किया था) या 'उचित' विधि का उपयोग करते हैं, हमें सामान्य त्रुटि हैंडलिंग कोड को पुन: प्रयोज्य करने के आधार पर निर्णय लेने की आवश्यकता है।

  • सामान्य त्रुटि हैंडलिंग कोड पूरी तरह से आवेदन भर में विभिन्न वर्गों में अन्य कार्यों के द्वारा पुन: प्रयोज्य है, तो यह शायद एक आंतरिक या सार्वजनिक समारोह, जो एक अलग वर्ग में हो सकता है किया जाना चाहिए कि अगर कोड संगठन बनाता है अधिक समझदार

  • यदि सामान्य त्रुटि हैंडलिंग कोड केवल उसी वर्ग में अन्य फ़ंक्शन द्वारा पुन: प्रयोज्य है, तो यह संभवतः एक ही कक्षा में एक निजी कार्य होना चाहिए।

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

तीसरे मामले में, ऐसा करने के लिए कोई स्पष्ट 'सर्वश्रेष्ठ तरीका' नहीं है क्योंकि दोनों एक ही लक्ष्य को प्राप्त करने के लिए पूरी तरह से वैध तरीके हैं। मेरी प्रवृत्ति एक प्रतिनिधि का उपयोग करना होगा जब आम कोड छोटा होता है और/या आपको चरवाहों को कैप्चर करने जैसे प्रतिनिधियों के कुछ व्यवहार की आवश्यकता होती है।

अब, सवाल पर वापस आकर, मैंने एक प्रतिनिधि का उपयोग करके कोड क्यों लिखा? मुझे इस बारे में कोई जानकारी नहीं थी कि त्रुटि प्रबंधन कोड पुनः उपयोग करने योग्य था या नहीं, इसलिए मैंने माना कि यह नहीं था, और एक प्रतिनिधि का उपयोग करने का फैसला किया क्योंकि मुझे लगा कि लोगों को यह समझने में आसान लगेगा कि यह 'उचित' हो सकता है। विधि (जैसा कि आपके पास है) जबकि यदि मैंने 'उचित' फ़ंक्शन का उपयोग दिखाया है तो लोगों को यह एहसास नहीं होगा कि एक प्रतिनिधि एक विकल्प होगा।

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