2009-04-02 11 views
18

क्या कन्स्ट्रक्टर कहने से पहले स्थैतिक क्षेत्र की शुरुआत पूरी होनी चाहिए?स्थिर क्षेत्र प्रारंभिकरण सी # में कैसे काम करता है?

निम्न प्रोग्राम आउटपुट प्रदान करता है जो मुझे गलत लगता है।

new A() 
_A == null 
static A() 
new A() 
_A == A 

कोड:

public class A 
{ 
    public static string _A = (new A()).I(); 

    public A() 
    { 
     Console.WriteLine("new A()"); 
     if (_A == null) 
      Console.WriteLine("_A == null"); 
     else 
      Console.WriteLine("_A == " + _A); 
    } 

    static A() 
    { 
     Console.WriteLine("static A()"); 
    } 

    public string I() 
    { 
     return "A"; 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     var a = new A(); 
    } 
} 

उत्तर

22

यह सही है।

आपके स्थैतिक प्रारंभकर्ता, फिर स्थिर कन्स्ट्रक्टर आपके मानक कन्स्ट्रक्टर से पहले चलाया जाता है, लेकिन जब यह चलता है, तो यह नया ए() का उपयोग कर रहा है, इसलिए आपके गैर स्थैतिक कन्स्ट्रक्टर पथ से गुजर रहा है। यह आपके द्वारा देखे जाने वाले संदेशों का कारण बनता है।

यहाँ निष्पादन का पूरा पथ है:

जब आप अपने प्रोग्राम में पहली कॉल var a = new A();, यह पहली बार एक पर पहुंचने पर है।

यह A._A

के स्थिर प्रारंभ बंद को सक्रिय कर देगा इस बिंदु पर, A._A साथ _A = (new A()).I();

यह


Console.WriteLine("new A()"); 
if (_A == null) 
    Console.WriteLine("_A == null");   

हिट के बाद से इस बिंदु पर, _a नहीं किया गया है का निर्माण लौटा, निर्मित प्रकार (अभी तक) के साथ सेट करें।

अगला, स्थिर निर्माता A { static A(); } चलाया गया है। यह "स्थैतिक ए()" संदेश प्रिंट करता है।

अंत में, अपने मूल बयान (var a = new A();) निष्पादित किया जाता है, लेकिन इस बिंदु पर, स्टैटिक्स निर्माण कर रहे हैं, तो आप अंतिम प्रिंट मिलता है।

+0

डैंग! मुझे इससे हराएं! –

+0

सभी उचित सम्मान के साथ ... स्थिर कन्स्ट्रक्टर पहले नहीं चलता है। स्थिर क्षेत्र प्रारंभकर्ता पहले चलता है। – Prankster

+1

ए_ए का निर्माण स्थैतिक कन्स्ट्रक्टर में होता है। यह सिर्फ इतना है कि संकलक सी # स्थिर कन्स्ट्रक्टर में घोषित कोड से पहले स्थिर कन्स्ट्रक्टर (.cctor) में सभी फ़ील्ड प्रारंभिकरणों को पूर्ववत करता है। –

-1

हां, स्थिर क्षेत्र प्रारंभिकता को कन्स्ट्रक्टर कहने से पहले पूरा करना चाहिए। लेकिन आप असामान्य स्थिति में कंपाइलर डालते हैं और यह सिर्फ इस नियम का पालन नहीं कर सकता है।

यह दिलचस्प चाल है, लेकिन यह सामान्य आवेदन में होने वाला नहीं है।

1

मुझे वास्तव में विश्वास है कि यह आपके विचारों को कर रहा है। आपके परीक्षण से यह कहना मुश्किल हो जाता है।

आपका _a

public static string _A = (new A()).I(); 

पहले एक का एक नया उदाहरण बनाता है के लिए initalization, इस प्रकार नए ए() और _a = बातिल के अपने लेखन। क्योंकि यह शुरू होने पर शून्य था, क्योंकि यह प्रारंभिक है। एक बार initalized, स्थिर कन्स्ट्रक्टर कहा जाता है, जो नया उदाहरण देता है।

0

ऐसा लगता है कि संकलक अपेक्षा कर रहा है।

1 - सभी स्थिर कोड निष्पादित होने पर (फ़ील्ड पहले, तो स्थिर निर्माता) कक्षा में:

public static string _A = (new A()).I(); 

// and 

static A() 
{ 
    Console.WriteLine("static A()"); 
} 

2 - कक्षा निर्माता कहा जाता है:

public A() 
{ 
    Console.WriteLine("new A()"); 
    if (_A == null) 
     Console.WriteLine("_A == null"); 
    else 
     Console.WriteLine("_A == " + _A); 
} 

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

0

एक अतिरिक्त पक्ष टिप्पणी - सी # विनिर्देश (मैं 4.0 पर देख रहा हूँ, लेकिन यह भी 3.0 में है) का कहना है 10.5.5.1 स्टेटिक फील्ड प्रारंभ में:

तो एक स्थिर निर्माता (§10.12) वर्ग में मौजूद है, स्थिर क्षेत्र initializers के निष्पादन तुरंत पहले क्रियान्वित कि स्थिर निर्माता के लिए होता है। अन्यथा, स्थिर क्षेत्र initializers एक कार्यान्वयन पर निर्भर समय पर क्रियान्वित कर रहे हैं उस वर्ग के एक स्थिर क्षेत्र का पहली बार उपयोग करने से पहले।

आपके पास एक स्थिर कंस्ट्रक्टर है, इसलिए "अन्यथा" खंड लागू नहीं होता है। लेकिन मुझे लगता है यह आपके सवाल का पता चला है कि अगर आप एक स्थिर निर्माता नहीं है, स्थिर क्षेत्र initializers 'एक कार्यान्वयन पर निर्भर समय में' क्रियान्वित किया जा सकता के लिए प्रासंगिक जानकारी है। यदि आपके स्थिर क्षेत्र प्रारंभकर्ता डेटा प्रारंभ या वस्तु के निर्माण के कुछ प्रकार है जो आप स्थिर क्षेत्र में ही तक पहुँचने के बिना पर भरोसा कर रही है यह कोई फर्क कर सकता है।

यह गूढ़ है, मुझे लगता है, लेकिन मैंने देखा कि आज ऐसा होता है क्योंकि सी # 3.0 और 4.0 के बीच 'कार्यान्वयन-निर्भर समय' बदल गया है - कम से कम जिस स्थिति में मैं देख रहा था। निश्चित रूप से आसान समाधान सरल है - बस एक स्थिर निर्माता जोड़ने ...

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