जॉन स्कीट स्पष्टीकरण द्वारा सिंगलटन


214
public sealed class Singleton
{
    Singleton() {}

    public static Singleton Instance
    {
        get
        {
            return Nested.instance;
        }
    }

    class Nested
    {
        // Explicit static constructor to tell C# compiler
        // not to mark type as beforefieldinit
        static Nested() {}
        internal static readonly Singleton instance = new Singleton();
    }
}

मैं C # में अपने वर्तमान आवेदन में जॉन स्कीट के सिंगलटन पैटर्न को लागू करना चाहता हूं ।

मुझे कोड पर दो संदेह हैं

  1. नेस्टेड क्लास के अंदर बाहरी वर्ग तक पहुंचना कैसे संभव है? मेरा मतलब

    internal static readonly Singleton instance = new Singleton();

    क्या किसी चीज को बंद कहा जाता है?

  2. मैं इस टिप्पणी को समझने में असमर्थ हूं

    // Explicit static constructor to tell C# compiler
    // not to mark type as beforefieldinit
    

    यह टिप्पणी हमें क्या सुझाव देती है?


12
हाहा मुझे लगा कि मैंने कहा था कि थोड़ा चिंतित था lol ... एक अलग जॉन नोलन निकला
जॉन एंटनी डैनियल नोलन

14
दो चीजें सार्वभौमिक रूप से स्वीकार की जाती हैं: सूरज पूर्व से उगता है और जॉन स्कीट हमेशा सही होता है। लेकिन मैं अभी तक पूर्व के बारे में निश्चित नहीं हूं: P
akhil_mittal

2
@ thepirat000 - यदि वह केवल SO / मेटा पर एक भागीदार था, तो मैं असहमत हो सकता हूं, लेकिन प्रोग्रामिंग की वास्तविक दुनिया में उसका पर्याप्त प्रभाव है जो वास्तव में वैध हो सकता है - मुझे यकीन है कि किसी ने इसे एक बिंदु या किसी अन्य पर बनाया है ।
कोड जॉनी

8
मेटा पर इस प्रश्न के वर्गीकरण पर चर्चा की जा रही है ।
BoltClock

जवाबों:


359
  1. नहीं, इसका क्लोजर से कोई लेना-देना नहीं है। एक नेस्टेड क्लास के पास अपने बाहरी वर्ग के निजी सदस्यों तक पहुंच होती है, जिसमें निजी कंस्ट्रक्टर भी शामिल है।

  2. मेरे लेख कोफील्डफील्ड पर पढ़ें । आप नो-ऑप स्टैटिक कंस्ट्रक्टर को चाह सकते हैं या नहीं भी सकते हैं - यह इस बात पर निर्भर करता है कि आलस आपको क्या गारंटी देता है। आप जानते हैं कि नेट 4 होना चाहिए में परिवर्तन वास्तविक प्रकार प्रारंभ अर्थ विज्ञान कुछ हद तक (अभी भी कल्पना के भीतर है, लेकिन पहले की तुलना में lazier)।

क्या आपको वास्तव में इस पैटर्न की आवश्यकता है? क्या आप सुनिश्चित हैं कि आप इससे दूर नहीं हो सकते:

public sealed class Singleton
{
    private static readonly Singleton instance = new Singleton();
    public static Singleton Instance { get { return instance; } }

    static Singleton() {}
    private Singleton() {}
}

12
@ आनंदि: नहीं, यह ठीक है। आप शिकायत करने के लिए JetBrains मेल करना चाह सकते हैं :)
जॉन स्कीट

2
@JonSkeet, मैंने अभी इस बारे में JetBrains के लिए एक चिंता जताई (# RSRP-274373)। आइए देखें कि वे क्या लेकर आ सकते हैं। :)
अनिंद्य चटर्जी

3
@ मोहन: तुम नहीं। AppDomain की अवधि के लिए एक सिंगलटन रहता है।
जॉन स्कीट

2
@JonSkeet किसी भी कारण से उपयोग न करने के लिए Lazy<T>ताकि आपको जादुई BeforeFieldInitसाइड-इफेक्ट के लिए एक स्थिर निर्माता घोषित न करना पड़े?
एड टी

3
FieldBeforeInitहै MahaBharataसेMicrosoft
अमित कुमार घोष

49

प्रश्न (1) के बारे में: जॉन का उत्तर सही है, क्योंकि वह कक्षा को 'नेस्टेड' निजी रूप से चिह्नित करता है, इसे सार्वजनिक या आंतरिक :-) नहीं बनाकर। आप इसे 'निजी' जोड़कर स्पष्ट रूप से कर सकते हैं:

    private class Nested

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

इसलिए यदि आप नहीं चाहते कि रनटाइम खेतों को 'सक्रिय' करने से पहले उनका उपयोग करें, तो एक स्थिर कंस्ट्रक्टर जोड़ें।

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

यह जॉन के पोस्ट को सिंगलटन के बारे में बताता है , जो इस प्रश्न का अंतर्निहित विषय है। ओह और संदेह :-)

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

मामले में आप सोच रहे हैं: मैं कभी भी सिंगलटन # 6 का उपयोग नहीं करूंगा क्योंकि यह आसानी से अपवादों के साथ गतिरोध और अप्रत्याशित व्यवहार का कारण बन सकता है। विवरण के लिए, देखें: आलसी का लॉकिंग मोड , विशेष रूप से एक्ज़ीक्यूशनएंड रिपब्लिकेशन।


62
Regarding question (1): The answer from Jon is correct ...जॉन स्कीट हमेशा सही होता है ....
नोक्टिस

72
एक जॉन स्कीट प्रश्न के बारे में एक उत्तर देने का प्रयास करने के लिए अतिरिक्त अंक जिसमें जॉन स्कीट पहले ही उत्तर दे चुका है।
Valdetero

8
@valdetero हाहाहा। यह ... hahaha +1
akinuri
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.