2009-04-15 16 views

उत्तर

14

फ़ील्ड स्वचालित रूप से प्रकार के लिए लॉजिकल शून्य में प्रारंभ हो जाते हैं; यह निहित है। चर को "निश्चित असाइनमेंट" का पालन करना होगा, इसलिए को पढ़ा जाने से पहले असाइन किया जाना चाहिए।

ECMA 334v4

§17.4.4 फील्ड प्रारंभ

एक क्षेत्र का प्रारंभिक मूल्य, चाहे तो वह एक स्थिर क्षेत्र या एक उदाहरण क्षेत्र हो, डिफ़ॉल्ट मान है (§12.2) फ़ील्ड का प्रकार। से पहले किसी फ़ील्ड के मान का निरीक्षण करने के लिए यह संभव नहीं है इस डिफ़ॉल्ट प्रारंभ में हुआ है, और इस प्रकार कोई फ़ील्ड इस प्रकार "अनियमित" नहीं है।

और

§12। चर

... एक चर को निश्चित रूप से असाइन किया जाएगा (§12.3) इससे पहले मूल्य प्राप्त किया जा सकता है। ...

+0

कि सिर्फ सवाल दोहरा रहा है। पर क्यों? –

+0

@YairHalberstadt जो इस पर निर्भर करता है कि "क्यों?" एक नियम या नियम के पीछे कारण का मतलब है। मैंने पहले जवाब दिया, जो तर्कसंगत सवाल का जवाब देता है; पल के लिए: क्योंकि जब तक आप पर विचार किया है निर्माता श्रृंखलन, आभासी तरीकों निर्माण के दौरान बुलाया जा रहा है, और तथ्य यह है कि आईएल स्तर पर आधार कंस्ट्रक्टर्स कॉल श्रृंखला में किसी भी बिंदु पर कहा जा सकता है - यह कुछ भी कहने के लिए लगभग असंभव हो जाता है क्षेत्र प्रारंभिक के बारे में समझदार; समान रूप से, फ़ील्ड को ओवरलैप किया जा सकता है जिससे अंतरिक्ष को शून्य करने के लिए और भी महत्वपूर्ण हो जाता है, इसलिए कोई इनिट तकनीकी रूप से आवश्यक नहीं है - इसके विपरीत ... –

+0

@YairHalberstadt स्थानीय चर, जिनके पास बहुत आसान असाइनमेंट जांच है, जहां अनियंत्रित आमतौर पर एक त्रुटि होती है, और जहां हम शून्यिंग छोड़ सकते हैं (हालांकि वर्तमान रनटाइम कभी नहीं करता है, आईआईआरसी)। –

4

यह वास्तव में नहीं होना चाहिए। आपकी त्रुटि दूसरी पंक्ति पर होनी चाहिए, पहले नहीं, और ऐसा होना चाहिए क्योंकि आपने इसे आरंभ करने से पहले इसका उपयोग किया था।

कंपाइलर आपकी मदद कर रहा है।

तो उन्हें आदत के रूप में प्रारंभ न करें, इसके बजाय कंपाइलर आपकी मदद करें!

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

यदि आप चर 0 को चर शुरू करते हैं, तो आप उस लाभ को दूर ले जाते हैं।

+0

मैंने इसे प्रारंभ करने से पहले टेस्ट 1 का भी उपयोग किया था, लेकिन यह ठीक था –

+0

हां, वही जांच कक्षा चर के साथ सहायक नहीं है - जब तक आप उन्हें अंतिम नहीं बनाते, तब तक पथ का पता लगाने का कोई तरीका नहीं है, तो यह आश्वस्त होना चाहिए कि वे हैं कन्स्ट्रक्टर में भरा (एक अच्छा विचार जहां संभव हो) –

+0

हालांकि इसकी पथ जांच बहुत फैंसी नहीं है। उदा। मान लें कि आपके पास ऐसा कुछ है: 'bool a, b = true; अगर (बी) ए = सच; बूल सी = ए; '। तीसरा कथन ** ** त्रुटि उत्पन्न करेगा, भले ही हम, इंसान, स्पष्ट रूप से देखें कि ''** ** ** तब तक शुरू किया जाएगा। कंपाइलर परिस्थितियों में नहीं दिखता है - यहां तक ​​कि जब वे बहुत सरल और हमेशा सत्य होते हैं। (और इसलिए यह अधिक जटिल मामलों पर भी लागू होता है।) – Sushi271

2

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

स्थानीय चर के लिए, यह पता लगाने के लिए भी बहुत आसान है कि सभी कोड पथ प्रारंभिक होने की संभावना है, जबकि यह निर्धारित करने के लिए कोई अच्छा हेरिस्टिक नहीं है कि पूरे कार्यक्रम में सभी कोड पथ उपयोग से पहले प्रारंभिक गारंटी की गारंटी देते हैं या नहीं। एक पूरी तरह से सही उत्तर impossible in both cases है, क्योंकि सभी सीएस छात्रों को पता होना चाहिए।

12

मार्क का जवाब विस्तारित, स्थानीय परिवर्तनीय प्रारंभिक सत्यापन प्रक्रिया से भी संबंधित है।
CLI की आवश्यकता है कि किसी भी निरीक्षण कोड में (जो है, मॉड्यूल कि स्पष्ट रूप से सत्यापन प्रक्रिया को छोड़ने के लिए SecurityPermission विशेषता से SkipVerfication संपत्ति का उपयोग कर पूछा नहीं था), सभी स्थानीय चर इससे पहले कि वे उपयोग कर रहे हैं प्रारंभ किया जाना चाहिए। ऐसा करने में विफल होने के परिणामस्वरूप VerficationException फेंक दिया जाएगा।

ज्यादा दिलचस्प है कि संकलक स्वतः ही हर विधि स्थानीय चर का उपयोग करता है पर .locals init ध्वज जोड़ता है। यह ध्वज जेआईटी कंपाइलर को कोड उत्पन्न करने का कारण बनता है जो सभी स्थानीय चर को उनके डिफ़ॉल्ट मानों में प्रारंभ करता है। मतलब है, भले ही आप पहले से ही अपने स्वयं के कोड में उन्हें प्रारंभ कर दिया है, JIT .locals init ध्वज का पालन करने और उचित प्रवर्तन कोड उत्पन्न होगा। यह "डुप्लिकेट आरंभीकरण" विन्यास कि अनुकूलन, JIT कम्पाइलर दोहराव का पता लगाने और प्रभावी ढंग से "मृत कोड" (स्वत: जनरेट प्रारंभ दिनचर्या उत्पन्न कोडांतरक निर्देश पर दिखाई नहीं देगा) के रूप में यह व्यवहार करेगा अनुमति देते हैं के बाद से प्रदर्शन प्रभावित नहीं करता।

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

एक इस विषय पर और अधिक व्यापक विवरण यहां पाया जा सकता: Behind The .locals init Flag

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