5

मैंने विजुअल स्टूडियो के बारे में कुछ अनोखा देखा है। , अबविजुअल स्टूडियो शून्य संदर्भ चेतावनी - क्यों कोई त्रुटि नहीं?

class Foo 
{ 
    public void Bar() 
    { 
     string s; 
     int i = s.Length; 
    } 
} 

अभी यह एक त्रुटि के रूप में s.Length में s का प्रतीक होगा, कि "Use of unassigned local variable 's'": सबसे पहले, एक समारोह में कहीं इस (सी #) लिखकर देखें। दूसरी ओर, इस कोड का प्रयास करें:

class Foo 
{ 
    private string s; 
    public void Bar() 
    { 
     int i = s.Length; 
    } 
} 

यह संकलन होगा, और एक चेतावनी के साथ private string s में s रेखांकित करते हुए कहा कि "Field 'Foo.s' is never assigned to, and will always have its default value null"।

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

उत्तर

8

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

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

तो यह डिज़ाइन द्वारा है।

0

एकमात्र अनुमान मैं कर सकता हूं कि दूसरे उदाहरण में, प्रतिबिंब के माध्यम से बदला जा सकता है (बाध्यकारीफ्लैग का उपयोग करके। निजी सदस्य तक पहुंचने के लिए निजी)।

0

पहला नमूना रों में एक स्थानीय चर रहा है और संकलक easialy जांच कर सकते हैं कि रों varible पहले यह प्रयोग किया जाता है नहीं सौंपा गया था।

दूसरे में, s एक वैश्विक चर है और यह संभव है कि इसे कक्षा में कहीं और शुरू किया गया हो।

+0

नहीं वैश्विक, यह एक उदाहरण है -खेत। –

3

दूसरे उदाहरण के लिए कोड मान्य है, यह शायद सही ढंग से नहीं चल सकता है। यहां कई मामले हैं जिनमें यह प्रोग्राम "सफलतापूर्वक"

  • निष्पादित कर सकता है संकलक 100% सही नहीं है। प्रतिबिंब के माध्यम से एक उदाहरण संशोधित किया गया है, तो "एस" के लिए एक गैर-शून्य मान होना संभव है।
  • कार्यक्रम त्रुटि बिना कार्य कर सकता है, तो विधि बार कभी
  • नहीं बुलाया जाता है इस कार्यक्रम के एक परीक्षण कार्यक्रम जो परीक्षण कारणों के लिए एक NullReferenceException ट्रिगर कर रहा है हो सकता है
संबंधित मुद्दे