एक-पंक्ति विधियों में रिटर्न वैल्यू और रिटर्न स्टेटमेंट की गणना को विभाजित करें?


26

मैंने एक सहकर्मी के साथ एक returnबयान को तोड़ने और दो पंक्तियों में वापसी मूल्य की गणना करने वाले बयान के बारे में चर्चा की है ।

उदाहरण के लिए

private string GetFormattedValue()
{
    var formattedString = format != null ? string.Format(format, value) : value.ToString();
    return formattedString;
}

के बजाय

private string GetFormattedValue()
{
    return format != null ? string.Format(format, value) : value.ToString();
}

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

मेरा सवाल है, अगर कोड को कम स्पष्ट लिखने के लिए अभी भी एक वैध बिंदु है, तो बस एक झलक को डीबग करना आसान है? विभाजन गणना और विवरण के साथ संस्करण के लिए कोई और तर्क हैं return?


18
वीएस पर काम नहीं कर रहा है, लेकिन आपको लगता है कि आप एक जटिल अभिव्यक्ति पर एक सशर्त ब्रेकपॉइंट सेट नहीं कर सकते हैं (या इसे दर्ज करने के लिए जटिल होगा), इसलिए संभवतः सुविधा के लिए, अलग-अलग विवरणों में असाइन किया गया और वापस आ जाएगा। कंपाइलर शायद किसी भी तरह दोनों के लिए एक ही कोड के साथ आएगा।
टॉफ्रो

1
यह संभवतः भाषा-निर्भर है, खासकर उन भाषाओं में जहां चर (संभवतः जटिल) ऑब्जेक्ट व्यवहार में सूचक-व्यवहार के बजाय होते हैं। @Paul K का कथन संभवतः सूचक व्यवहार वाली भाषाओं के लिए सही है, जिन भाषाओं में वस्तुओं का सरल मूल्य व्यवहार है, और परिपक्व, उच्च गुणवत्ता वाले संकलक वाली भाषाएं हैं।
MSalters 10

4
"चूंकि VisualStudio हमें बयानों का बहुत विस्तृत निरीक्षण करने की अनुमति देता है, जब ब्रेक प्वाइंट के कारण निष्पादन रोक दिया जाता है" - ऐसा है। यदि फ़ंक्शन एक संरचना को एक से अधिक सदस्यों के साथ लौटाता है तो आपको रिटर्न वैल्यू कैसे मिलती है? (और उस सुविधा के लिए समर्थन सबसे अच्छे रूप में धब्बेदार है, वहाँ बहुत सारे संयोजन हैं जहाँ आपको रिटर्न मान बिल्कुल नहीं मिलता है)।
Voo

2
डिबग में कोई व्यक्ति "स्टेटमेंट का बहुत विस्तृत निरीक्षण" करता है, जिसे कोई TODAY का उपयोग कर रहा है, उसे कोड लिखने का एक बुरा विकल्प बनाता है ताकि किसी भी डीबगर में डीबग करना आसान हो?
इयान

16
एनाय ने उन्हें पूरे समारोह के शरीर को कम करकेprivate string GetFormattedValue() => string.Format(format ?? "{0}", value);
ग्राहम

जवाबों:


46

प्रस्तुत चर का परिचय एक प्रसिद्ध परावर्तन है जो कभी-कभी जटिल अभिव्यक्तियों को बेहतर पठनीय बनाने में मदद कर सकता है। हालाँकि, दिखाए गए मामले में,

  • अतिरिक्त चर कुछ भी "समझा" नहीं करता है जो आसपास के विधि नाम से स्पष्ट नहीं है
  • बयान और भी लंबा हो जाता है, इसलिए (थोड़ा) कम पठनीय

इसके अलावा, विज़ुअल स्टूडियो डीबगर के नए संस्करण ज्यादातर मामलों में एक शानदार रिटर्न पेश किए बिना फ़ंक्शन का रिटर्न मान दिखा सकते हैं (लेकिन सावधान रहें, कुछ कैविट हैं, इस पुराने एसओ पोस्ट और अलग-अलग उत्तरों पर एक नज़र है )।

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


मैं सहमत हूँ, भी, कि निश्चित रूप से ऐसे मामले हैं जिनमें यह उपयोगी है, इसमें कोई संदेह नहीं है।
पॉल केर्चर

2
मैं आमतौर पर resultचर के नाम के रूप में उपयोग करता हूं । इतना लंबा और डिबग करना आसान नहीं है
edc65

26
@ edc65: एक सामान्य नाम की तरह result , अक्सर कोड में शोर जोड़ता है और शायद ही कभी पठनीयता को बढ़ाता है, जो वास्तव में मेरे उत्तर का बिंदु है। इसे संदर्भ में उचित ठहराया जा सकता है जहां यह डिबगिंग में मदद करता है, लेकिन मैं उस डिबगर का उपयोग करने से बचता हूं, जिसे अलग चर की आवश्यकता नहीं है।
डॉक ब्राउन

6
@JonHanna रास्ता उपकरण मेरे अनुसार लंबा है। नाम resultजानकारी को बताता है कि यह फ़ंक्शन से उत्पन्न मान है, ताकि आप फ़ंक्शन के वापस आने से पहले इसे देख सकें।
edc65

1
@ edc65 लेकिन यह उपयोगी दिखता है। इसलिए अब जब मैं आपका कोड पढ़ रहा हूं तो मुझे तुरंत एहसास नहीं हुआ कि यह नहीं है। तो आपका कोड कम पठनीय हो गया है।
जॉन हैना

38

तथ्यों को देखते हुए कि:

क) अंतिम कोड पर कोई प्रभाव नहीं पड़ता है क्योंकि कंपाइलर चर को अनुकूलित करता है।

बी) यह अलग होने से डिबगिंग क्षमता को बढ़ाता है।

मैं व्यक्तिगत रूप से इस निष्कर्ष पर पहुंचा हूं कि उन्हें 99% समय के लिए अलग करना एक अच्छा अभ्यास है।

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


9
यह मेरे लिए सही उत्तर है। इससे ब्रेकपॉइंट सेट करना और डिबगिंग के समय मूल्य देखना आसान हो जाता है, और इसका कोई नकारात्मक पहलू नहीं है कि मैं इसके बारे में जानता हूं।
मैथ्यू जेम्स ब्रिग्स

पॉइंट बी के लिए, विजुअल स्टूडियो कोड में, बस रिटर्न पर ब्रेकपॉइंट लगाएं और फिर एक्सप्रेशन जोड़ें: GetFormattedValue () और वह परिणाम दिखाएगा जब ब्रेकपॉइंट हिट होता है, इसलिए अतिरिक्त लाइन की आवश्यकता नहीं होती है। लेकिन स्थानीय लोगों को अतिरिक्त लाइन के साथ देखना आसान है क्योंकि इसे डीबगर में किसी भी अतिरिक्त अभिव्यक्ति को जोड़ने की आवश्यकता नहीं होगी। तो, वास्तव में व्यक्तिगत पसंद की बात है।
जॉन रेन्नोर

3
वापसी मूल्य के लिए @JonRaynor, फ़ंक्शन के समापन ब्रैकेट पर ब्रेकपॉइंट डालें। यह कई रिटर्न वाले कार्यों में भी, लौटा हुआ मूल्य पकड़ता है।
बाल्ड्रिक

16

अक्सर, किसी परिणाम को नाम देने के लिए केवल एक चर का परिचय देना बहुत उपयोगी होता है जब यह कोड को अधिक स्व-दस्तावेजीकरण बनाता है। इस मामले में यह एक कारक नहीं है क्योंकि चर नाम विधि के नाम के समान है।

ध्यान दें कि एक पंक्ति विधियों का कोई अंतर्निहित मूल्य नहीं है। यदि कोई परिवर्तन अधिक पंक्तियों का परिचय देता है, लेकिन कोड को स्पष्ट करता है, तो यह एक अच्छा बदलाव है।

लेकिन सामान्य तौर पर, ये निर्णय आपकी व्यक्तिगत प्राथमिकताओं पर अत्यधिक निर्भर होते हैं। उदाहरण के लिए, मैं दोनों समाधानों को भ्रमित करता हूं क्योंकि सशर्त ऑपरेटर का अनावश्यक रूप से उपयोग किया जा रहा है। मैं एक if-statement पसंद करता। लेकिन आपकी टीम में आप विभिन्न सम्मेलनों पर सहमत हो सकते हैं। फिर अपने सम्मेलनों का सुझाव दें। यदि कन्वेंशन इस तरह के एक मामले पर चुप हैं, तो ध्यान दें कि यह एक बहुत ही मामूली बदलाव है जो लंबे समय में मायने नहीं रखता है। यदि यह पैटर्न बार-बार होता है, तो शायद एक चर्चा शुरू करें कि आप इन मामलों को कैसे संभालना चाहते हैं। लेकिन यह "अच्छे कोड" और "शायद एक छोटे से बेहतर कोड" के बीच बालों को विभाजित करता है।


1
"मैं दोनों समाधानों को भ्रमित करता हूं क्योंकि सशर्त ऑपरेटर का अनावश्यक रूप से उपयोग किया जा रहा है।" - यह एक वास्तविक दुनिया उदाहरण नहीं है, मुझे बस जल्दी से कुछ बनाना था। बेशक यह सबसे अच्छा उदाहरण नहीं हो सकता है।
पॉल केर्चर

4
+1 अनिवार्य रूप से यह कहने के लिए कि यह "रडार के नीचे" अंतर है (जो अन्य चीजों के बराबर है) यह इस लायक नहीं है कि इसके बारे में परेशान हो।
ट्रिपहाउंड

3
@ मिंडविन, जब मैं टर्नरी ऑपरेटर का उपयोग करता हूं, तो मैं आमतौर पर इसे कई लाइनों में विभाजित करता हूं ताकि यह स्पष्ट हो जाए कि सच्चा मामला क्या है और झूठा मामला क्या है।
आर्टुरो टॉरेस सांचेज़

2
@ ArturoTorresSánchez मैं वह भी करता हूं, लेकिन एक के बजाय एक ?और :मैं उपयोग करता हूं if() {और } else {- - - - \\ :)
माइंडविन

3
@ मिंडविन, लेकिन मैं ऐसा नहीं कर सकता, जब मैं एक अभिव्यक्ति के बीच में हूं (जैसे ऑब्जेक्ट इनिशलाइज़र)
आर्टुरो टोरेस

2

आपके सवालों के जवाब में:

मेरा सवाल है, अगर कोड को कम स्पष्ट लिखने के लिए अभी भी एक वैध बिंदु है, तो बस एक झलक को डीबग करना आसान है?

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

डिबगिंग को आसान बनाना (लगभग) " छोटी योग्यता " का कभी नहीं है क्योंकि कुछ अनुमानों के अनुसार प्रोग्रामर का 50% समय डीबगिंग ( रिवर्सेबल डिबगिंग सॉफ्टवेयर ) खर्च होता है ।

विभाजित गणना और वापसी विवरण के साथ संस्करण के लिए कोई और तर्क हैं?

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

नोट: व्यावसायिक नियम डेटाबेस में बेहतर तरीके से परोसे जा सकते हैं क्योंकि वे अक्सर बदल सकते हैं। फिर भी, इस क्षेत्र में स्पष्ट कोडिंग अभी भी सर्वोपरि है। ( बिजनेस रूल्स इंजन कैसे बनाएं )


1

मैं आगे भी जाना चाहता हूँ:

private string GetFormattedValue()
{
    if (format != null) {
        formattedString = string.Format(format, value);
    } else {
        formattedString = value.ToString()
    }
    return formattedString;
}

क्यूं कर?

अधिक जटिल तर्क के लिए टर्नरी ऑपरेटरों का उपयोग करना अपठनीय होगा, इसलिए आप अधिक जटिल कथनों के लिए उपरोक्त शैली का उपयोग करेंगे। हमेशा इस शैली का उपयोग करके, आपका कोड मानव के लिए पार्स करने के लिए सुसंगत और आसान होता है। इसके अतिरिक्त, इस तरह की स्थिरता (और कोड लिंट और अन्य परीक्षणों का उपयोग करके) आप goto failटाइप त्रुटियों से बच सकते हैं।

एक और लाभ यह है कि आपकी कोड कवरेज रिपोर्ट आपको बताएगी कि क्या आप भूल गए हैं कि परीक्षण शामिल करना formatअशक्त नहीं है। यह टर्नरी ऑपरेटर के लिए मामला नहीं होगा।


मेरा पसंदीदा विकल्प - यदि आप "संभव भीड़ के रूप में जल्दी वापसी" और एक विधि से कई रिटर्न के खिलाफ नहीं हैं:

private string GetFormattedValue()
{
    if (format != null) {
        return string.Format(format, value);
    }

    return value.ToString();
}

इसलिए, आप अंतिम रिटर्न को देखने के लिए देख सकते हैं कि डिफ़ॉल्ट क्या है।

हालांकि लगातार होना महत्वपूर्ण है - और आपके सभी तरीके एक या दूसरे सम्मेलन का पालन करते हैं।


1
पहला उदाहरण बुरा अभ्यास है क्योंकि value.ToString()अनावश्यक रूप से कहा जाता है जब प्रारूप गैर-अशक्त होता है। सामान्य स्थिति में, इसमें गैर-तुच्छ गणना शामिल हो सकती है, और प्रारूप स्ट्रिंग सहित संस्करण से अधिक समय लग सकता है। उदाहरण के लिए, valueपीआई एक मिलियन दशमलव स्थानों पर स्टोर करता है, और एक प्रारूप स्ट्रिंग जो केवल पहले कुछ अंकों का अनुरोध करता है।
स्टीव

1
private string GetFormattedValue() => string.Format(format ?? "{0}", value); वही क्यों प्रभावित नहीं करता है, और डिबगर पर भरोसा करने के बजाय शुद्धता सुनिश्चित करने के लिए यूनिट परीक्षणों का उपयोग करें।
बेरिन लोरिट्श

1
जबकि मैं मानता हूं कि एक टर्नरी कम स्पष्ट हो सकती है, अशक्त टर्मिनेटर चीजों को अधिक स्पष्ट कर सकता है। कम से कम इस मामले में।
बेरिन लोरिट्स्क

1
प्रिय डायरी, आज मैंने पढ़ा है कि सुप्रसिद्ध और संक्षिप्त कोड का उपयोग करते हुए सुप्रसिद्ध (लगभग 40 वर्षों से मौजूद) प्रतिमानों, मुहावरों और संचालकों का उपयोग करते हुए उद्धरण, दोहरे उद्धरण, चतुराई से दोहरे उद्धरण होने के नाते है, निर्विरोध - लेकिन इसके बजाय मौखिक रूप से कोड का उल्लंघन करते हुए लिखना DRY और उपर्युक्त संचालकों, मुहावरों और प्रतिमानों का उपयोग न करते हुए, कुछ भी बचने की कोशिश करने के बजाय, जो संभवतया पांच साल की उम्र में ही बिना किसी पूर्व प्रोग्रामिंग पृष्ठभूमि के क्रिप्टिक लगता है - इसके बजाय स्पष्टता है । नरक, मुझे असली बूढ़ा हो जाना चाहिए, मेरी प्रिय डायरी ... मुझे मौका मिलने पर सीखना चाहिए था।
vaxquis

1
"अधिक जटिल तर्क के लिए टर्नरी ऑपरेटरों का उपयोग करना अपठनीय होगा" जबकि यह वास्तव में मामला है (और मैंने लोगों को तर्क को ओवरक्लम्प्लीकेट करते हुए देखा है) यह ओपी कोड के लिए सही नहीं है, और टर्नरी ऑपरेटरों के लिए भी कोई खास बात नहीं है। मैं पूरे विश्वास के साथ कह सकता हूं कि लाइन बहुत लंबी है। gist.github.com/milleniumbug/cf9b62cac32a07899378feef6c06c776 मैं इसका सुधार कैसे करूंगा।
सहस्राब्दी

1

मुझे नहीं लगता कि इस तरह की तकनीक को डिबग करने की आवश्यकता के द्वारा उचित ठहराया जा सकता है। मैंने इस दृष्टिकोण का खुद से हजार बार सामना किया है, और समय-समय पर मैं ऐसा करता रहता हूं, लेकिन मैं हमेशा ध्यान रखता हूं कि मार्टिन फाउलर ने डिबगिंग के बारे में क्या कहा :

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


मार्टिन फाउलर एक बुद्धिमान व्यक्ति हैं और मुझे उनके (और आपके) विचारों को पढ़ने में बहुत मज़ा आया। जबकि मेरा दृढ़ विश्वास है कि परीक्षण आवश्यक है और उस प्रयास में अधिक समय बिताना चाहिए, इस तथ्य को कि हम सभी पतनशील मानव हैं, यह सुझाव देते हैं कि परीक्षण की कोई भी मात्रा सभी कीड़े नहीं मिटाएगी। इसलिए, डिबगिंग हमेशा कार्यक्रम के विकास और समर्थन प्रक्रिया का एक हिस्सा होगा।
कथा .५२१५०

1

मुझे लगता है कि कुछ लोग प्रश्न के स्पर्शरेखा के मुद्दों पर त्रस्त हो रहे हैं, जैसे कि टर्नरी ऑपरेटर। हां, बहुत से लोग इसे नफरत करते हैं, इसलिए शायद वैसे भी ऊपर लाना अच्छा है।

अपने प्रश्न के फ़ोकस के बारे में, दिए गए कथन को एक चर द्वारा संदर्भित करने के लिए बाहर ले जाना ...

यह प्रश्न 2 धारणाएं बनाता है जिनसे मैं असहमत हूं:

  1. यह दूसरा संस्करण अधिक स्पष्ट या पढ़ने में आसान है (मैं कहता हूं कि विपरीत सच है), और

  2. कि हर कोई Visual Studio का उपयोग करता है। मैंने कई बार विजुअल स्टूडियो का उपयोग किया है और इसे ठीक-ठीक उपयोग कर सकता हूं, लेकिन मैं आमतौर पर कुछ और उपयोग कर रहा हूं। एक देव वातावरण जो एक विशिष्ट आईडीई को बाध्य करता है वह है जिसमें मुझे संदेह है।

एक नामित चर के लिए कुछ तोड़कर शायद ही कभी पढ़ने के लिए कुछ भी कठिन हो जाता है, यह लगभग हमेशा विपरीत होता है। जिस विशिष्ट तरीके से कोई इसे करता है, वह समस्या पैदा कर सकता है, जैसे कि यदि कोई स्व-प्रलेखन ओवरलोर्ड करता है var thisVariableIsTheFormattedResultAndWillBeTheReturnValue = ...तो जाहिर है कि यह खराब है, लेकिन यह एक अलग मुद्दा है। var formattedText = ...ठीक है।

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

सामान्य तौर पर, और आपने सामान्य नियम के लिए पूछा (आपका उदाहरण सिर्फ यह था कि, सामान्यीकृत रूप का एक उदाहरण), वेरिएंट 1 (2-लाइनर) के पक्ष में किए गए सभी बिंदु सही हैं। वे अच्छे दिशानिर्देश हैं। लेकिन दिशानिर्देशों को लचीला बनाने की जरूरत है। उदाहरण के लिए, अब मैं जिस परियोजना पर काम कर रहा हूं , उसमें प्रति पंक्ति अधिकतम 80 वर्ण हैं, इसलिए मैंने बहुत सी रेखाएं विभाजित की हैं, लेकिन मैं आमतौर पर 81-85 वर्णों की रेखाएं पाता हूं, जो पठनीयता को विभाजित या कम करने के लिए अजीब होंगे और मैं उन्हें छोड़ दूंगा सीमा।

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.