जहां उपयोग किया जाता है, उसके पास चर क्यों घोषित करें?


10

मैंने लोगों को यह कहते सुना है कि चर को यथासंभव उनके उपयोग के करीब घोषित किया जाना चाहिए। मुझे यह समझ में नहीं आता है।

उदाहरण के लिए, यह नीति बताएगी कि मुझे यह करना चाहिए:

foreach (var item in veryLongList) {
  int whereShouldIBeDeclared = item.Id;
  //...
}

लेकिन निश्चित रूप से इसका मतलब यह है कि एक नया बनाने के ओवरहेड्स intहर पुनरावृत्ति पर खर्च होते हैं। क्या इसका उपयोग करना बेहतर नहीं होगा:

int whereShouldIBeDeclared;
foreach (var item in veryLongList) {
  whereShouldIBeDeclared = item.Id;
  //...
}

कृपया कोई समझा सकता है?


3
यह एक बहुत ही खराब भाषा होगी जो उन दो मामलों को अलग तरह से व्यवहार करती है।
पॉल टॉम्बलिन

5
आप एक झूठे आधार से शुरुआत करते हैं। कृपया इस सवाल का मेरा जवाब देखें: stackoverflow.com/questions/6919655/…
CesarGon

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

4
यदि दो कोड उदाहरणों में एक महत्वपूर्ण शब्दार्थ अंतर है, तो वे अलग-अलग काम करते हैं। आपको वही करना चाहिए जो आप करना चाहते हैं। नियम के बारे में जहां आप चर घोषित करते हैं, केवल उन मामलों पर लागू होता है जहां यह कोई अर्थपूर्ण अंतर नहीं करता है।
डेविड श्वार्ट्ज

4
पैमाने के विपरीत छोर पर विचार करें - सब कुछ एक वैश्विक चर है। निश्चित रूप से spectrum निकट उपयोग के लिए घोषित ’इस स्पेक्ट्रम का बेहतर अंत है?
JBRWilkinson

जवाबों:


27

यह कई लोगों के बीच एक शैली नियम है, और यह जरूरी नहीं कि सभी संभावित नियमों में से सबसे महत्वपूर्ण नियम है जिस पर आप विचार कर सकते हैं। आपका उदाहरण, क्योंकि इसमें एक इंट शामिल है, सुपर सम्मोहक नहीं है, लेकिन आपके पास निश्चित रूप से उस लूप के अंदर एक महंगी-से-निर्माण वाली वस्तु हो सकती है, और लूप के बाहर ऑब्जेक्ट के निर्माण के लिए शायद एक अच्छा तर्क है। हालाँकि, यह इस नियम के खिलाफ एक अच्छा तर्क नहीं देता है क्योंकि पहले, कई अन्य स्थान हैं जो यह लागू कर सकते हैं कि एक लूप में महंगी वस्तुओं का निर्माण शामिल नहीं है, और दूसरा, एक अच्छा अनुकूलक (और आपने टैग किया है C #, तो आपके पास एक अच्छा अनुकूलक है) लूप के बाहर आरंभीकरण को फहरा सकता है।

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

if (flag) limit += factor;

झंडा, सीमा और कारक क्या थे, इसके बारे में बहुत सारे सुराग नहीं थे। हंगेरियन नोटेशन जैसे नामकरण सम्मेलनों को इसके साथ मदद करने के लिए अपनाया गया था, और इसलिए नियम थे कि वे जहां उपयोग किया जाता है, उसके करीब चीजों की घोषणा करना। बेशक, इन दिनों, यह सब के बारे में है refactoring, और कार्य आम तौर पर एक पृष्ठ लंबे समय से कम कर रहे हैं, जिससे यह मुश्किल है कि जहां चीजें घोषित की जाती हैं और जहां उनका उपयोग किया जाता है, के बीच बहुत दूरी तय करना। आप 0-20 की सीमा में काम कर रहे हैं और क्विबलिंग कर रहे हैं कि शायद 7 इस विशेष उदाहरण में ठीक है, जबकि नियम बनाने वाले को 7 लाइन दूर पाने के लिए प्यार किया होगा और किसी से 700 से नीचे बात करने की कोशिश कर रहा था। और उसके ऊपर, Visual Studio में, आप किसी भी चीज़ पर माउस ले जा सकते हैं और उसका प्रकार देख सकते हैं, क्या यह एक सदस्य चर है, और इसी तरह। इसका मतलब है कि लाइन को घोषित करते हुए देखने की आवश्यकता कम है।

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


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

2
एक int बनाने का ओवरहेड छोटा है। यदि आप कुछ जटिल निर्माण कर रहे हैं, तो ओवरहेड एक बड़ा सौदा होगा।
केट ग्रेगोरी

17
यह न केवल अपने प्रकार और ऐसे देखने में सक्षम होने का सवाल है। यह जीवन भर का सवाल भी है। यदि वैरिएबल "वाइबल" को पहली बार उपयोग करने से पहले 30 लाइनों के रूप में घोषित किया जाता है, तो 30 लाइनें हैं जिसमें "वाइबल" के गलत उपयोग के परिणामस्वरूप बग हो सकता है। यदि इसे इस्तेमाल करने से ठीक पहले घोषित किया जाता है, तो उन 30 पिछली लाइनों में "वाइबल" का उपयोग करने से बग का परिणाम नहीं होगा। यह बजाय एक संकलक त्रुटि का कारण होगा।
माइक शेरिल 'कैट रिकॉल'

इस मामले में, प्रत्येक लूप में एक नया उदाहरण नहीं बनाया जाता है। एक एकल शीर्ष-स्तरीय चर बनाया जाता है और इसका उपयोग प्रत्येक पुनरावृत्ति के लिए किया जाता है (आईएल को देखें)। लेकिन यह एक कार्यान्वयन विवरण है।
thecoop

"विज़ुअल स्टूडियो में, आप किसी भी चीज़ पर माउस ले जा सकते हैं और देख सकते हैं" आदि की परिभाषा में नेविगेट भी है, जिसमें शॉर्टकट है F12जो अपरिहार्य है।
स्टुपरयूसर

15

लूप के अंदर चर को परिभाषित करने से यह केवल उस लूप के लिए दृश्यता स्थानीय होती है। पाठक के लिए इसके कम से कम 3 फायदे हैं:

  1. चर परिभाषा और किसी भी संबंधित टिप्पणी को ढूंढना आसान है
  2. पाठक जानता है कि इस चर का उपयोग कभी और नहीं किया जाता है, जहां (उम्मीद के लिए कोई निर्भरता नहीं)
  3. जब कोड लिखा या संपादित किया जाता है, तो कोई मौका नहीं है कि आप उस चर को संदर्भित करने के लिए लूप के बाहर एक ही चर नाम का उपयोग कर सकते हैं अन्यथा, आप गलती से प्राप्त कर सकते हैं।

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


4

लोग जितना संभव हो उतना उनके उपयोग के करीब कहते हैं , वे यह नहीं कह रहे हैं कि आपको हर समय ऐसा करना चाहिए, क्योंकि वे कुछ मामले हैं जो चर को कम से कम दायरे में घोषित करते हैं, कुछ ओवरहेड का कारण बनेंगे। उस बयान के मुख्य कारण पठनीयता और चर दे रहे हैं। सबसे छोटा स्कोप जो आप कर सकते हैं।


4

यद्यपि यह पठनीयता के साथ मदद करता है, पठनीयता इस मामले में प्राथमिक विचार नहीं है, और आधुनिक आईडीई इस नियम की आवश्यकता को कम नहीं करते हैं।

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

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


1

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

आपको बस अपना रास्ता चुनना है और उसका पालन करना है।


2
यह सिर्फ एक राय नहीं है, क्या यह है? क्या सॉफ़्टवेयर इंजीनियरिंग अनुसंधान ने कम से कम 1980 के दशक से लाइव समय और बग की संख्या के बीच संबंध को प्रलेखित नहीं किया है?
माइक शेरिल 'कैट रिकॉल'

1

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

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