2013-07-18 9 views
5

मेरा मतलब यह प्रश्न बहुत ही व्यक्तिपरक नहीं है।एक एकल वस्तु के खिलाफ LINQ का उपयोग करना एक बुरा अभ्यास माना जाता है?

मैंने कुछ समय के लिए यह Google'd किया लेकिन इस मुद्दे को हल करने के लिए कोई विशिष्ट जवाब नहीं मिला। बात यह है कि, मुझे लगता है कि मुझे LINQ पर कुछ हद तक आदी हो रही है। मैंने LINQ से SQL, Xml, आदि जैसे अन्य चीजों के साथ सूचियों पर क्वेरी करने के लिए पहले ही LINQ का उपयोग किया है। लेकिन फिर कुछ ने मुझे मारा: "क्या होगा अगर मैंने इसे एक ऑब्जेक्ट से पूछने के लिए इस्तेमाल किया?" तो मैंने किया। ग्रेनेड लॉन्चर के साथ एक फ्लाई को मारने की कोशिश करना गलत लगता है। हालांकि हम सभी सहमत हैं कि यह देखने के लिए कलात्मक रूप से सुखद होगा।


मैं विचार यह बहुत पठनीय, मुझे नहीं लगता कि इस के लिए के बारे में कोई प्रदर्शन के मुद्दों है, लेकिन मैं आपको एक उदाहरण दिखा सकते हैं।

किसी वेब एप्लिकेशन में, मुझे अपनी कॉन्फ़िगरेशन फ़ाइल (web.config) से एक सेटिंग पुनर्प्राप्त करने की आवश्यकता है। लेकिन यदि कुंजी मौजूद नहीं है तो इसका डिफ़ॉल्ट मान होना चाहिए। साथ ही, मुझे जिस मान की आवश्यकता है वह एक दशमलव है, स्ट्रिंग नहीं, जो ConfigurationManager.AppSettings["myKey"] से डिफ़ॉल्ट वापसी है। इसके अलावा, मेरी संख्या 10 से अधिक नहीं होनी चाहिए और यह नकारात्मक नहीं होना चाहिए। मुझे पता है कि मैं इसे लिख सकता हूं:

string cfg = ConfigurationManager.AppSettings["myKey"]; 
decimal bla; 
if (!decimal.TryParse(cfg,out bla)) 
{ 
    bla = 0; // 0 is the default value 
} 
else 
{ 
    if (bla<0 || bla>10) 
    { 
     bla = 0; 
    } 
} 

जो जटिल नहीं है, संकलित नहीं है, और पढ़ने में आसान है।

// initialize it so the compiler doesn't complain when you select it after 
decimal awesome = 0; 
// use Enumerable.Repeat to grab a "singleton" IEnumerable<string> 
// which is feed with the value got from app settings 
awesome = Enumerable.Repeat(ConfigurationManager.AppSettings["myKey"], 1) 
    // Is it parseable? grab it 
    .Where(value => decimal.TryParse(value, out awesome)) 
    // This is a little trick: select the own variable since it has been assigned by TryParse 
    // Also, from now on I'm working with an IEnumerable<decimal> 
    .Select(value => awesome) 
    // Check the other constraints 
    .Where(number => number >= 0 && number <= 10) 
    // If the previous "Where"s weren't matched, the IEnumerable is empty, so get the default value 
    .DefaultIfEmpty(0) 
    // Return the value from the IEnumerable 
    .Single(); 
टिप्पणियों के बिना

यह इस तरह दिखता है,: बहरहाल, यह मैं यह किया कैसे पसंद है

decimal awesome = 0; 
awesome = Enumerable.Repeat(ConfigurationManager.AppSettings["myKey"], 1) 
    .Where(value => decimal.TryParse(value, out awesome)) 
    .Select(value => awesome) 
    .Where(number => number >= 0 && number <= 10) 
    .DefaultIfEmpty(0) 
    .Single(); 

मैं नहीं जानता कि यदि मैं केवल एक यहाँ हूँ, लेकिन मुझे लगता है कि दूसरी विधि पहले की तुलना में अधिक "कार्बनिक" है। LINQ की वजह से यह आसानी से डिबगबल नहीं है, लेकिन मुझे लगता है कि यह काफी असफल है। कम से कम यह मैंने लिखा था। वैसे भी, यदि आपको डीबग करने की आवश्यकता है, तो आप केवल घुंघराले ब्रेसिज़ जोड़ सकते हैं और linq विधियों के अंदर बयान वापस कर सकते हैं और इसके बारे में खुश रह सकते हैं।

मैं इसे थोड़ी देर के लिए कर रहा हूं, और यह चीजें "लाइन प्रति पंक्ति, चरण दर चरण" करने से कहीं अधिक प्राकृतिक लगता है। इसके अलावा, मैंने बस एक बार डिफ़ॉल्ट मान निर्दिष्ट किया है। और यह एक पंक्ति में लिखा गया है जो DefaultIfEmpty कहता है, इसलिए यह बहुत सरल है।

एक और प्लस, मैं निश्चित रूप से ऐसा नहीं करता अगर मुझे लगता है कि क्वेरी वहां से लिखी गई तुलना में बहुत बड़ी होगी। इसके बजाय, मैं linq महिमा के छोटे टुकड़ों में तोड़ने के लिए समझना और डीबग करना आसान होगा।

मुझे लगता है यह आसान एक चर काम देख सकते हैं और स्वचालित रूप से सोचने के लिए: यह आप, elses, स्विच, और आदि, और अगर यह पता लगाने की कोशिश यह मान सेट करने के बजाय भारतीय विदेश सेवा को देखो करना था क्या है वे सूत्र का हिस्सा हैं या नहीं।

और यह डेवलपर्स को गलत स्थानों पर अवांछित साइड इफेक्ट्स लिखने से रोकता है, मुझे लगता है।

लेकिन अंत में, कुछ कह सकते हैं यह बहुत hackish, या बहुत रहस्यमय लग रहा है।

एक बुरा अभ्यास माना जाता है एक वस्तु के खिलाफ LINQ का उपयोग कर रहा है:

तो मैं हाथ में प्रश्न के साथ आते हैं?

+0

मुझे लगता है कि यह थोड़ा सा व्यक्तिपरक हो सकता है। –

+0

अगर मुझे उस कोड की समीक्षा करनी पड़ी, तो मैं खुद को मार दूंगा। कृपया अपने सहकर्मियों पर विचार करें। – fcuesta

+0

@fcuesta हाहा मैंने ऐसा सोचा, और मैं उससे डरता था। शायद मुझे हाल ही में अनुभव कर रहे इस "कलात्मक प्रोग्रामिंग" चीज को छोड़ने की जरूरत है। सब कुछ एक के बाद एक लाइनर होने की जरूरत नहीं है। –

उत्तर

7

मैं हाँ कहता हूं, लेकिन यह वास्तव में वरीयता तक है। यह निश्चित रूप से नुकसान है, लेकिन मैं इसे आप को छोड़ दूंगा। हालांकि आपका मूल कोड बहुत आसान हो सकता है।

string cfg = ConfigurationManager.AppSettings["myKey"]; 
decimal bla; 
if (!decimal.TryParse(cfg,out bla) || bla < 0 || bla > 10) 
    bla = 0; // 0 is the default value 

यह "शॉर्ट सर्किट" मूल्यांकन, जिसका अर्थ है कि कार्यक्रम अन्य शर्तों की जाँच एक बार पहली सच हालत पाया जाता है बंद हो जाएगा की वजह से काम करता है।

+0

आप सही हैं, मैं ऊपर उठाया। क्या आप इस तरह के लेखन कोड के कुछ 'नुकसान' निर्दिष्ट कर सकते हैं, कुछ सहकर्मियों को 'मुश्किल' या 'अनावश्यक परिसर' ढूंढने के अलावा? धन्यवाद। –

+0

ठीक है, एक के लिए, आपको इटेटरेटर के लिए राज्य मशीन के लिए ऑब्जेक्ट बनाना होगा। इसके बाद, आप 'भयानक' चर के चयन के साथ साइड इफेक्ट का लाभ उठा रहे हैं। अगर कोई गड़बड़ हो जाता है और आपको 2 पुनरावृत्तियों मिलते हैं, तो यह समस्याग्रस्त हो जाता है। इसलिए यदि कोई यह भी समझ में नहीं आता कि 'आउट' कैसे काम करता है, तो वे उस बाद के चयन से उलझन में जा रहे हैं। तीसरा, आपको बंद होने के साथ कई प्रतिनिधियों की आवश्यकता होगी जब आपको उनकी आवश्यकता नहीं होगी। चौथा, आपके पास कभी भी आवश्यकता के मुकाबले अधिक विधि कॉल हैं। –

+0

मुझे लगता है, आपके पास एक बिंदु है। मैं इसे उत्तर के रूप में स्थापित कर रहा हूं, क्योंकि आपने इसे स्पष्ट रूप से उचित ठहराया है, हालांकि मैं अभी भी यह देखने के लिए थोड़ा और खोदूँगा कि क्या मैं वास्तव में कोड को "अतिसंवेदनशील" कर रहा हूं या बस इसे एक अलग (लेकिन आवश्यक रूप से खराब) प्रतिमान पर स्विच कर रहा हूं। धन्यवाद। –

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

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