2015-09-01 15 views
20
using System; 
using System.Collections.Generic; 

class Parent 
{ 
    public Child Child { get; set; } 
} 

class Child 
{ 
    public List<string> Strings { get; set; } 
} 

static class Program 
{ 
    static void Main() { 
     // bad object initialization 
     var parent = new Parent() { 
     Child = { 
      Strings = { "hello", "world" } 
     } 
     }; 
    } 
} 

उपरोक्त कार्यक्रम ठीक संकलित का कारण बनता है, लेकिन साथ वस्तु संदर्भ वस्तु का एक उदाहरण के लिए सेट नहीं रनटाइम पर दुर्घटनाओं।आरंभ किया जा रहा सूची संपत्ति NullReferenceException

यदि आप उपरोक्त स्निपेट में देखते हैं, तो मेरे पास बाल गुणों को प्रारंभ करते समय छोड़ा गया है।

जाहिर प्रारंभ करने में सही तरीका है: जब वह पहली बार निर्माण देखता

 var parent = new Parent() { 
     Child = new Child() { 
      Strings = new List<string> { "hello", "world" } 
     } 
     }; 

मेरा प्रश्न क्यों सी # संकलक शिकायत नहीं करता है?

टूटा प्रारंभिक वैध वाक्यविन्यास क्यों है?

 var parent = new Parent() { 
     Child = { 
      Strings = { "hello", "world" } 
     } 
     }; 

उत्तर

4

दूसरा वाक्यविन्यास केवल पढ़ने योग्य गुणों के लिए मान्य है। यदि आप संबंधित रचनाकारों में बाल और स्ट्रिंग गुणों को प्रारंभ करने के लिए कोड बदलते हैं, तो वाक्यविन्यास काम करता है।

class Parent 
{ 
    public Parent() 
    { 
     Child = new Child(); 
    } 

    public Child Child { get; private set; } 
} 

class Child 
{ 
    public Child() 
    { 
     Strings = new List<string>(); 
    } 
    public List<string> Strings { get; private set; } 
} 

static class Program 
{ 
    static void Main() 
    { 
     // works fine now 
     var parent = new Parent 
     { 
      Child = 
      { 
       Strings = { "hello", "world" } 
      } 
     }; 

    } 
} 
+0

Ah readonly गुण, धन्यवाद! – Ajai

+4

संग्रह प्रारंभकर्ताओं के पास केवल-पढ़ने योग्य गुणों के साथ कुछ लेना देना नहीं है। यह कोड काम करता है क्योंकि आप 'स्ट्रिंग्स = नई सूची ();' कन्स्ट्रक्टर में नहीं, क्योंकि संपत्ति में 'निजी सेट' है। – GSerg

+0

कोड फिर से पढ़ें। बाल संपत्ति संग्रह नहीं है, यह केवल पढ़ने की संपत्ति है। –

17

यह सिंटैक्स टूटा नहीं है, यह आप एक ऐसी संपत्ति पर ऑब्जेक्ट प्रारंभकर्ता का उपयोग करते हैं जो तुरंत नहीं है। क्या आप ने लिखा

var parent = new Parent(); 
parent.Child.Strings = new List<string> { "hello", "world" }; 

करने के लिए विस्तारित किया जा सकता है कौन सा फेंकता NullReferenceException: आप संपत्ति Child जबकि Child अभी भी null है द्वारा संपत्ति Strings निहित आवंटित करने के लिए कोशिश कर रहे हैं। पहले Child को तुरंत चालू करने के लिए एक कन्स्ट्रक्टर का उपयोग करके, इसका ख्याल रखता है।

10

प्रारंभिकरण में कुछ भी गलत नहीं है, लेकिन यह उन वस्तुओं को शुरू करने की कोशिश कर रहा है जो मौजूद नहीं हैं।

कक्षाएं कंस्ट्रक्टर्स कि वस्तुओं को बनाने के है, तो initialisation काम करता है:

class Parent { 
    public Child Child { get; set; } 
    public Parent() { 
    Child = new Child(); 
    } 
} 

class Child { 
    public List<string> Strings { get; set; } 
    public Child() { 
    Strings = new List<string>(); 
    } 
} 
0

एक अशक्त हमेशा संकलन समय पर लिए जाँच की जानी नहीं कर सकते संदर्भित। यद्यपि कंपाइलर कभी-कभी इसे आवंटित करने से पहले एक चर का उपयोग करने की चेतावनी देता है। कंपाइलर सही ढंग से काम करता है। यह एक रन-टाइम त्रुटि है।

4

आपको यह समझना प्रतीत होता है कि संग्रह प्रारंभकर्ता क्या करता है।

यह एक मात्र वाक्य रचनात्मक चीनी है जो ब्रेसिज़ में सूची को series of calls to Add() method में परिवर्तित करती है जिसे संग्रह वस्तु को प्रारंभ में परिभाषित किया जाना चाहिए।
आपका = { "hello", "world" } इसलिए है, क्योंकि

.Add("hello"); 
.Add("world"); 

जाहिर है इस एक ही प्रभाव एक NullReferenceException साथ विफल हो जाएगा यदि संग्रह नहीं बनाई गई है है।

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