2010-01-06 9 views
6

चेक इस कोड को ..क्यों संदर्भ प्रकार शून्य के लिए शुरू नहीं किए गए हैं?

string str; 

    if (str.Contains("something..")) 
    { 
    } 

संकलक इस कोड

असाइन नहीं किए गए स्थानीय चर 'str'

एक संदर्भ प्रकार क्यों आरंभ नहीं किया है है की

उपयोग के लिए इस त्रुटि फेंकता शून्य करने के लिए?

बस जिज्ञासा से जानना चाहते हैं।

मैं यह भी जानना चाहता हूं कि नीचे दिए गए कोड के लिए क्या होता है। यह असाइनमेंट कैसे काम करता है?

string str = null; 

उत्तर

20

केवल क्षेत्रों (चर श्रेणी स्तर पर घोषित) स्वचालित रूप से प्रारंभ कर रहे हैं:

  • मूल्य प्रकार उनके डिफ़ॉल्ट मान पर प्रारंभ कर रहे हैं।
  • संदर्भ प्रकार null संदर्भ में आरंभ किए गए हैं।

जो आप घोषित कर रहे हैं वह एक विधि के अंदर "स्थानीय चर" है। मूल्य चर या संदर्भ प्रकार होने के बावजूद स्थानीय चर स्वचालित रूप से प्रारंभ नहीं होते हैं।

मैं यह भी जानना चाहता हूं कि नीचे दिए गए कोड के लिए क्या होता है। यह असाइनमेंट कैसे काम करता है?

यह असाइनमेंट एक ldnull अनुदेश एक stloc अनुदेश (मामले में यह बाहर अनुरूप होता है नहीं, निश्चित रूप से) और अधिक महत्वपूर्ण बात यह निश्चित कार्य के लिए संकलक के डाटा प्रवाह विश्लेषण नियमों को संतुष्ट करता है के द्वारा पीछा के साथ शून्य मान के साथ स्थानीय चर initializes। सी # विनिर्देश निश्चित असाइनमेंट नामक एक अवधारणा को परिभाषित करता है जो सुनिश्चित करता है कि एक चर को पहले उपयोग से पहले असाइन किया गया हो।

+0

क्या आप उन फ़ील्ड के बारे में बात कर रहे हैं जो संदर्भ-प्रकार हैं और अभी भी शून्य के रूप में प्रारंभ किए गए हैं? तो इतना अंतर क्यों? –

+0

क्या बीच के बीच अंतर? स्थानीय होने के नाते या नहीं? –

+2

@ मेहरदाद: मुझे लगता है कि वह जानना चाहता है कि क्यों स्थानीय चर स्वचालित रूप से फ़ील्ड के विपरीत उनके डिफ़ॉल्ट मान में प्रारंभ नहीं होते हैं। कारण यह है क्योंकि यह पहले से ही एक अनुकूलन है। कंपाइलर सुरक्षित रूप से कह सकता है कि स्थानीय चर को एक मान दिया गया है या नहीं। यदि यह संकलक नहीं है संकलन समय पर एक त्रुटि फेंक देगा। यह अनुकूलन फ़ील्ड के लिए संभव नहीं होगा। –

-1

ध्यान रखें कि कॉलिंग एक नल स्ट्रिंग पर एक NullReferenceException फेंक देगा।

+0

यह बिल्कुल संकलित नहीं होगा। –

+0

मुझे लगता है मुझे याद आती है। मैंने सोचा था कि आप यह भी पूछ रहे थे कि क्या होगा यदि आपके पास स्ट्र चर को शून्य पर सेट करने वाला कोड था। उस मामले में अपवाद होगा। –

2

यह शून्य के लिए शुरू किया गया है। कंपाइलर ने आपको अपरिहार्य NullReferenceException को डीबग न करने के द्वारा सिर्फ एक पक्ष किया है।

+0

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

+0

Hmya, chicked-and- अंडे की समस्या वीबीएनईटी में इसकी अनुमति है, यह स्थानीय चर शुरू करने के लिए कोई आईएल उत्पन्न नहीं करता है। प्रारंभिकता जेआईटी कंपाइलर द्वारा की जाती है। –

+0

उपरोक्त उदाहरण को बदलते समय केवल नल के लिए स्ट्रिंग को जांचने के लिए - आप अभी भी संकलित नहीं कर सकते क्योंकि अनियमित वार्स नल के खिलाफ भी जांच नहीं सकते हैं। सी # और जावा के बीच स्विच करते समय कभी-कभी मुझे परेशान करता है। – FrankKrumnow

6

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

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

इसके अलावा, पर विचार करें:

while(whatever) 
{ 
    int i; 
    print(i); 
    i = i + 1; 
} 

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

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

मुझे नहीं पता कि आपके दूसरे प्रश्न का उत्तर कैसे दिया जाए क्योंकि मुझे नहीं पता कि "काम" से आपका क्या मतलब है। क्या आप मुझे बता सकते हैं कि "int x = 123;" काम करता है? एक बार जब मैं जानता हूं कि "काम" से आपका क्या मतलब है तो मैं वर्णन कर सकता हूं कि संदर्भ प्रकार कार्यों के चर के लिए शून्य को कैसे असाइन करना है।

+0

यह ध्यान देने योग्य है कि अगर किसी ने 'प्रिंट' लाइन को 'आउटसाइड ऑब्जेक्ट.प्रिंट (आउट i) में बदल दिया है;', किसी अन्य भाषा में नियमित रूप से लिखे गए कॉलिंग को कॉल करने से, संकलक स्वचालित रूप से यह सुनिश्चित करने के लिए कॉल उत्पन्न करेगा कि 'i' प्रारंभ किया जाएगा पहली कॉल से पहले, लेकिन बाद में कॉल से पहले इसे शुरू किया जा सकता है या नहीं। दरअसल, यदि 'zz' एक संरचना प्रकार है जिसका कन्स्ट्रक्टर बाहरी कोड पर 'आउट' पैरामीटर के रूप में 'this' को पास करता है, यहां तक ​​कि' var foo = new zz (2); जैसे एक कथन भी 'foo' को पूरी तरह से छूटा नहीं जा सकता है। – supercat