2009-07-14 17 views
21

स्वीकार करता है मैं एक स्थिर वर्ग या सिंगलटन क्लास बनाना चाहता हूं जो उसके कन्स्ट्रक्टर में किसी अन्य ऑब्जेक्ट के संदर्भ को स्वीकार करता हो। स्टेटिक कक्षाएं बाहर हैं, लेकिन मुझे लगा कि मैं एक सिंगलटन बना सकता हूं जो इसके कन्स्ट्रक्टर में पैरामीटर स्वीकार करता है। अब तक मुझे वाक्यविन्यास को समझने या गुमराह करने की कोई किस्मत नहीं है। क्या यह संभव है? यदि ऐसा है, तो मुझे इसे कैसे करना है?सी # सिंगलटन कन्स्ट्रक्टर के साथ जो पैरामीटर

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

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

उदाहरण के लिए, मैं सिंगलटन "स्टेटस" क्लास बनाना चाहता हूं, जो स्ट्रिंगबिल्डर ऑब्जेक्ट और ड्रॉ() विधि का मालिक है जिसे स्क्रीन पर स्ट्रिंगबिल्डर कहा जाता है। ड्रा() विधि को आकर्षित करने के लिए मेरे ग्राफ़िसडिवाइस के बारे में जानना आवश्यक है। तो क्या मैं इसे ऐसा करना चाहते हैं:

public class Status 
{ 
private static Status _instance; 
private StringBuilder _messages; 
private GraphicsDevice _gDevice; 

private Status(string message, GraphicsDevice device) 
{ 
    _messages.Append(message); 
    _gDevice = device; 
} 

// The following isn't thread-safe 

// This constructor part is what I'm trying to figure out 
public static Status Instance // (GraphicsDevice device) 
    { 
    get 
     { 
     if (_instance == null) 
      { 
      _instance = new Status("Test Message!", device); 
      } 
     return _instance; 
     } 
    } 

public void UpdateMessage 
... 

public void Draw() 
    { 
    // Draw my status to the screen, using _gDevice and _messages 
    } 
} 

सभी कोड पर, मैं अपने स्थिति सिंगलटन निकालते हैं और अपने विधि UpdateMessage() कहते हैं।

private Status _status = Status.Instance; // + pass reference to GraphicsDevice 
_status.UpdateMessage("Foo!"); 

फिर, अपने मुख्य वर्ग में मैं भी सिंगलटन पुनः प्राप्त करेगा और आकर्षित यह:

_status.Draw(); 

हाँ, इसका मतलब है कि मैं जहाँ भी सिंगलटन पुनः प्राप्त है, मैं में पारित करके ऐसा करने की आवश्यकता ग्राफिक्सडिवाइस के संदर्भ में, अगर पहली बार मैं सिंगलटन को तुरंत चालू करता हूं। और मैं अपने सिंगलटन क्लास में ग्राफिक्सडिवाइस के रूप में मौलिक के रूप में कुछ हासिल करने के लिए विभिन्न माध्यमों का उपयोग/कर सकता हूं, उदाहरण के लिए कहीं और एक सेवा पंजीकृत करें और स्थिति क्लास में वह सेवा प्राप्त करें। इस उदाहरण में काफी योगदान हुआ - मैं यह पता लगाने की कोशिश कर रहा हूं कि कुछ इस पैटर्न की तरह पहली जगह संभव है।

+1

जो मैं पूछ रहा था उसके बारे में एक बेहतर बेहतर स्पष्टीकरण जोड़ा गया। –

उत्तर

2

जो आप वर्णन कर रहे हैं वह जेनेरिक सिंगलटन है। यह इस तरह दिखता है:

public class SingletonProvider <T> where T:new() 
{ 
    SingletonProvider() {} 

    public static T Instance 
    { 
     get { return SingletonCreator.instance; } 
    } 

    class SingletonCreator 
    { 
     static SingletonCreator() { } 

     internal static readonly T instance = new T(); 
    } 
} 

http://www.codeproject.com/KB/cs/genericsingleton.aspx

+4

आप कैसे गारंटी दे सकते हैं कि आपके आवेदन में टाइप टी के कोई अन्य उदाहरण नहीं हैं? यह वास्तव में एक सिंगलटन नहीं है। –

+5

मुझे लगता है कि प्रश्न पूछने वाला व्यक्ति पहले से ही समझता है कि वह किसी और चीज़ के लिए प्रकार का उपयोग नहीं कर सकता है। उसने चाकू के लिए पूछा, मैंने उसे नहीं बताया कि इसके साथ क्या करना है। –

+1

सिंगलटन सिंगलटन से एक अलग प्रकार है, इसलिए इससे कोई फर्क नहीं पड़ता। जेनेरिक सिंगलटन केवल समझ में आता है अगर वे सिंगलेट बनाने के लिए बेस क्लास के रूप में कार्य करते हैं, तो मुझे कल्पना है। –

17

यह आम तौर पर एक बुरा विचार माना जाता है क्योंकि अगर आप या तो एक वस्तु संदर्भ या एक प्रकार तर्क यह है कि आप एक सिंगलटन की तरह आवरण में रैपिंग पर योजना स्वीकार करने के लिए जा रहे हैं आप गारंटी नहीं दे सकते कि आप AppDomain में उस प्रकार का एकमात्र उदाहरण रखते हैं।

सिंगलटन पैटर्न का पूरा बिंदु एक प्रकार के एक उदाहरण को नियंत्रित करना है ताकि उस प्रकार का केवल एक उदाहरण मौजूद हो। यदि आप किसी उदाहरण को पारित करने की अनुमति देते हैं या यदि आप एक सामान्य सिंगलटन प्रदाता बनाते हैं तो आप गारंटी नहीं दे सकते कि आपका उदाहरण केवल उदाहरण है।

मान लें कि मेरे पास SingletonFactory<T> है जो मुझे कारखाने में जाने वाले किसी भी प्रकार के आसपास एक सिंगलटन बनाने की अनुमति देगा।यह काफी आसान हो सकता है और मुझे इस तरह कुछ करने के लिए अनुमति होगी:

SingletonFactory<Foo>.Instance; 

लेकिन क्या मुझे भी ऐसा करने से बंद हो जाता है:

Foo foo = new Foo(); 

ओह, ऐसा Foo की तरह दिखता है एक सिंगलटन अब और नहीं है जैसा कि मैं चाहता हूं कि मैं इसके कई उदाहरण बना सकता हूं। सिंगलटन पैटर्न को काम करने के लिए आपको उस प्रकार को पूरी तरह से नियंत्रित करने में सक्षम होना चाहिए जिसके उदाहरण आपको प्रतिबंधित करने की आवश्यकता है। यही कारण है कि आपको मेरे SingletonFactory<T> जैसे कुछ भी उपयोग नहीं करना चाहिए।

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

2

आप विशेष रूप से इस तरह दिखता है के लिए पूछ रहे हैं क्या, मुझे लगता है:

public sealed class Singleton { 
    static Singleton instance = null; 
    static readonly object padlock = new Object(); 
    Object o; 

    Singleton(Object _o) { 
     o = _o; 
    } 

    public static Singleton Instance(Object _o) { 
     lock (padlock) { 
      if (instance == null) { 
       instance = new Singleton(_o); 
      } 
      return instance; 
     } 
    } 
} 

Singleton s = Singleton.Instance(new Object()); 

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

1

आपको एक निजी कन्स्ट्रक्टर की आवश्यकता है और फिर एक getInstance विधि की आवश्यकता है, यह विधि है कि कौन से परम प्राप्त करना चाहिए, कन्स्ट्रक्टर निजी होना चाहिए और इसमें पैराम भी हो सकते हैं, लेकिन प्राप्त करें इसे पास करना चाहिए, नहीं। बीटीडब्ल्यू, तुम क्या कर रहे हो? कुछ वास्तविक उदाहरण मदद कर सकते हैं।

0

एक बात आप कर सकते हैं सिंगलटन नमूना आप पाया के लिए चिपके हुए किया जा सकता है और सिर्फ एक संपत्ति उजागर (सेटर, यदि आवश्यक हो तो, साथ ही गेटर जोड़ने) और की तरह MySingleton.Instance.MyReference = new MyObject();

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

यदि आपको एक पठनीय व्यवहार करने की आवश्यकता है, तो आप MyReference Setter में अपवाद फेंक सकते हैं यदि कोई भी अलग ऑब्जेक्ट असाइन करना चाहता है, जबकि BeenInitialized सत्य पर सेट है।

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