2008-10-20 18 views
18

मुझे पता है कि क्या में के रूप में इनलाइन एक स्थिर सदस्य आरंभ के बीच अंतर है चाहते हैं:अंतर सी # में स्थिर चर इनलाइन या स्थिर निर्माता में आरंभ

class Foo 
{ 
    private static Bar bar_ = new Bar(); 
} 

या में के रूप में स्थिर निर्माता के अंदर यह आरंभ:

class Foo 
{ 
    static Foo() 
    { 
     bar_ = new Bar(); 
    } 
    private static Bar bar_; 
} 
+0

जांच: http://stackoverflow.com/a/40939743/4038978 –

उत्तर

17

आप अपने प्रकार में एक स्थिर निर्माता है, तो यह करने के लिए beforefieldinit झंडा नहीं रह गया है लागू किया जा रहा कारण प्रकार प्रारंभ बदल देता है।

यह प्रारंभिक क्रम को भी प्रभावित करता है - परिवर्तनीय प्रारंभकर्ता सभी स्थिर कन्स्ट्रक्टर से पहले निष्पादित किए जाते हैं।

यह तब तक है जब तक मुझे पता है।

+3

यह एक महत्वपूर्ण उदाहरण के लिए क्यों मायने रखता है: http://stackoverflow.com/questions/217932/whats-the-difference-in-these-ways-of-creating-the-static-instance-for-a-single # 218005 –

+0

आपके लिंक से: 'रनटाइम असेंबली को लोड करने के लिए टाइपिंग प्रारंभकर्ता को चलाने का निर्णय ले सकता है। मैं जेनेरिक कक्षाओं के साथ मानता हूं ('वर्ग नमूना ') नियम बदलते हैं? संकलन-समय संकल्प (उदा। सी ++) के साथ नियम समान होंगे, लेकिन .NET रन-टाइम रिज़ॉल्यूशन करता है। रनटाइम प्रत्येक संभावित संयोजन के लिए तत्काल नहीं होगा, और मुझे संदेह है कि असेंबली लोड करने पर यह देखने के लिए आगे बढ़ेगा कि किस प्रकार का उपयोग किया जाता है। –

+0

@NelsonRothermel: यह पहली बार टाइप प्रकार का उपयोग करने के प्रकार को शुरू करता है - इसलिए यदि आप 'Foo ' का उपयोग करते हैं, तो यह तब शुरू होगा, और बाद में टाइप प्रकार प्रारंभकर्ता को फिर से चलाएं यदि आप 'Foo ' का उपयोग करते हैं। –

3

इस मामले में मुझे विश्वास नहीं है कि वहां कोई व्यावहारिक अंतर है। यदि आपको स्थैतिक चर प्रारंभ करने में कुछ तर्क की आवश्यकता है - जैसे कि आप अलग-अलग स्थितियों के विभिन्न ठोस प्रकारों का उपयोग करना चाहते हैं - आप स्थिर कन्स्ट्रक्टर का उपयोग करेंगे। अन्यथा, मेरी पुस्तक में इनलाइन प्रारंभिक ठीक है।

class Foo 
{ 
    private static IBar _bar; 

    static Foo() 
    { 
     if(something) 
     { 
      _bar = new BarA(); 
     } 
     else 
     { 
      _bar = new BarB(); 
     } 
    } 
} 
+0

वास्तव में, यह एक बड़ा व्यावहारिक बना सकते हैं अंतर - यहां देखें (अंतर "काम करता है" बनाम "नहीं करता"): http://stackoverflow.com/questions/217932/whats-the-difference-in-these-ways-of-creating-the-static -instance-for-a-single # 218005 –

+0

मुझे स्थिति मिलती है आयन बहुत अजीब होने का वर्णन किया: | इसके बारे में सोचकर, मेरे सिंगलेट में मैं हमेशा दो स्थिर वस्तुओं, वास्तविक उदाहरण और लॉक करने के लिए एक ऑब्जेक्ट का उपयोग करता हूं। उदाहरण मैं हमेशा एक प्रॉपर्टी विधि में बना देता हूं, लॉक ऑब्जेक्ट मैं इनलाइन को तत्काल करता हूं। मैंने इससे पहले कभी नहीं सोचा था। –

+0

Tobjorn: ऐसा लगता है जैसे आप आमतौर पर लॉकिंग कर रहे हैं जब आपको इसकी आवश्यकता नहीं है :) (अधिकांश समय मुझे लगता है कि स्थिर प्रारंभिक गारंटी सिंगलेट्स के लिए पूरी तरह से पर्याप्त हैं।) –

-1

गोधूलि क्षेत्र जवाब: वहाँ निष्पादन इनलाइन initializers और ctor काम के बीच ... जब आप बूट करने के लिए उदाहरण और स्थिर सदस्यों और विरासत में मिश्रण की क्रम में एक अंतर है।

For static members, static initializers 
Static ctors (execute bottom up) 
Base static initializer 
Base static ctor and so on 

For instance members, initializers in current class execute first 
Then initializers in base class execute (up the chain) 
Then top-most base ctor is executed (and we walk down now. Instance ctors execute top-down) 
Finally current type's ctor is executed. 

उदाहरण :)

public class CBase 
    { 
     static Talkative m_Baseob1 = new Talkative("Base Static Initializer-"); 
     static Talkative m_Baseob2; 
     Talkative m_Baseob3 = new Talkative("Base Inst Initializer"); 
     Talkative m_Baseob4; 
     static CBase() 
     { 
      Console.WriteLine("***MethodBegin: Static Base Ctor"); 
      m_Baseob2 = new Talkative("Base Static Ctor"); 
      Console.WriteLine("***MethodEnd: Static Base Ctor"); 
     } 
     public CBase() 
     { 
      Console.WriteLine("***MethodBegin: Instance Base Ctor"); 
      m_Baseob4 = new Talkative("Base Instance Ctor"); 
      Console.WriteLine("***MethodEnd: Instance Base Ctor"); 
     } 
    } 
    public class CDerived : CBase 
    { 
     static Talkative m_ob1 = new Talkative("Derived Static Initializer"); 
     static Talkative m_ob2; 
     Talkative m_ob3 = new Talkative("Derived Inst Initializer"); 
     Talkative m_ob4; 
     static CDerived() 
     { 
      Console.WriteLine("***MethodBegin: Derived Static Ctor"); 
      m_ob2 = new Talkative("Derived Static Ctor"); 
      Console.WriteLine("***MethodEnd: Derived Static Ctor"); 
     } 
     public CDerived() 
     { 
      Console.WriteLine("***MethodBegin: Derived Instance Ctor"); 
      m_ob4 = new Talkative("Derived Instance Ctor"); 
      Console.WriteLine("***MethodEnd: Derived Instance Ctor"); 
     } 
    } 
    internal class Talkative 
    { 
     public Talkative(string sID) 
     { 
      Console.WriteLine(sID + " - Talkative created"); 
     } 
    } 

    # Main function somewhere 
    CDerived s = new CDerived(); 

आउटपुट:

Derived Static Initializer - Talkative created 

***MethodBegin: Derived Static Ctor 
Derived Static Ctor - Talkative created 
***MethodEnd: Derived Static Ctor 

Derived Inst Initializer - Talkative created 

Base Static Initializer- - Talkative created 

***MethodBegin: Static Base Ctor 
Base Static Ctor - Talkative created 
***MethodEnd: Static Base Ctor 

Base Inst Initializer - Talkative created 

***MethodBegin: Instance Base Ctor 
Base Instance Ctor - Talkative created 
***MethodEnd: Instance Base Ctor 

***MethodBegin: Derived Instance Ctor 
Derived Instance Ctor - Talkative created 
***MethodEnd: Derived Instance Ctor 
+0

यहां सीबीज़ स्थिर कन्स्ट्रक्टर को केवल इसलिए बुलाया जा रहा है क्योंकि सीडीरिव का एक उदाहरण बनाया जा रहा है। यदि आप केवल सीडीरिव में एक विधि को कॉल करते हैं जिसे सीबीज़ को छूने की आवश्यकता नहीं है, तो सीबीज़ के स्थिर निर्माता को बिल्कुल भी नहीं बुलाया जाएगा। –

+0

अगर मैंने ऐसा किया तो मुझे आश्चर्य होगा .. मैंने पहली वाक्य में विरासत का उल्लेख किया था। मेरा बिंदु: कैसे एक वैरिएबल प्रारंभ किया जाता है (फील्ड प्रारंभकर्ता या सीटीआर में), चाहे स्थैतिक/inst और चाहे वह एक प्रकार के पदानुक्रम में हो। लेकिन हाँ .. मेरा जवाब ओपी के क्यू के लिए थोड़ी अधिक है;) – Gishu

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