2011-09-28 5 views
5

सी # में जब एक नई वस्तु के साथ एक डिस्पोजेबल ऑब्जेक्ट वैरिएबल को फिर से सौंपना, यह स्मृति में कैसे काम करता है? क्या पुराने ऑब्जेक्ट पर कब्जा कर लिया गया मेमोरी स्पेस केवल नए ऑब्जेक्ट द्वारा ओवरराइट किया जाएगा? या क्या मुझे अभी भी संसाधनों को रिलीज़ करने के लिए Dispose() पर कॉल करना है?एक डिस्पोजेबल ऑब्जेक्ट वेरिएबल काम को फिर से सौंपना कैसे करता है?

DisposableThing thing; 

thing = new DisposableThing(); 
//....do stuff 
//thing.Dispose(); 
thing = new DisposableThing(); 
+0

मुझे नहीं पता कि आप जानते हैं या नहीं, लेकिन चूंकि आपने इस सवाल को [कचरा संग्रह] और [idisposable] के साथ टैग किया है, मैंने सोचा था कि मैं बस इतना कहूंगा कि कचरा कलेक्टर कभी भी 'आईडीस्पोजेबल' नहीं कहता है।) '। आपको स्पष्ट रूप से अपना कोड लिखना चाहिए ताकि जीसी को एकत्रित करने से पहले 'निपटान() 'कहा जा सके। – Enigmativity

+0

@ निष्क्रियता "माइक्रोसॉफ्ट-ordained" उदाहरणों में सभी को 'निपटान (झूठा)' का आह्वान करने वाला फाइनलाइज़र है (मुझे लगता है कि बाहरी संसाधनों को जारी होने का * मौका * सुनिश्चित करने के लिए यह आखिरी खाई प्रयास के रूप में किया जाता है)। माना जाता है कि जीसी और फाइनलइज़र दोनों चंचल जानवर हैं और आम तौर पर उन पर भरोसा नहीं किया जाना चाहिए जहां डिस्पोजेबल ऑब्जेक्ट्स का उपयोग किया जाता है ... वाईएमएमवी। –

+1

@pst - हाँ, वे करते हैं और मुझे लगता है कि भ्रम उत्पन्न होता है। .NET डेवलपर्स के लिए यह भी महत्वपूर्ण है कि यह भी समझें कि अंतिम गारंटी कभी भी कहलाए जाने की कोई गारंटी नहीं है, इसलिए किसी को यह सुनिश्चित करने की आवश्यकता होगी कि किसी का 'निपटान' विधि "वैकल्पिक" है यदि इसे इस पैटर्न का उपयोग करके कोड किया गया हो। – Enigmativity

उत्तर

3

भीतर किया जाना चाहिए यह वही काम करता है किसी भी अन्य असाइनमेंट के रूप में: =IDisposable परवाह नहीं करता है या कोई जादू नहीं करता है।

प्रारंभ में वैरिएबल को असाइन किया गया ऑब्जेक्ट Dispose को मैन्युअल रूप से (या बेहतर, using के साथ) आवश्यक रूप से आवंटित करना होगा। हालांकि, इस बिंदु पर Dispose पर कॉल करने के लिए हमेशा सही नहीं हो सकता है: जो ऑब्जेक्ट का मालिक है और जीवनकाल को नियंत्रित करता है?

क्या पुराने ऑब्जेक्ट पर कब्जा कर लिया गया मेमोरी स्पेस केवल नए ऑब्जेक्ट द्वारा ओवरराइट किया जाएगा?

लागू नहीं होता है। चर "नाम" वस्तुओं। एक ऑब्जेक्ट स्वयं है और एक चर एक चर है - ऑब्जेक्ट या "स्मृति में स्थान" नहीं। (एरिक लिपर्ट की टिप्पणी देखें: पूर्ववर्ती चर के उच्च स्तर का दृश्य है, जबकि एरिक की टिप्पणी सी # कार्यान्वयन, भावना, और शब्दावली में चरम रूप से अधिक सटीक रूप से प्रतिबिंबित करती है।)

चर केवल ऑब्जेक्ट जीवनकाल को प्रभावित करते हैं जैसे वे * रख सकते हैं वस्तु को पुनः प्राप्त करने से ऑब्जेक्ट (और इस प्रकार अंतिम रूप से चलने वाले [संभवतः] चलने वाले को अंतिम रूप से रोकें)। हालांकि, वेरिएबल अर्थात् जीवनकाल पर ऑब्जेक्ट्स को नियंत्रित नहीं करते हैं - एक ऑब्जेक्ट को पुनः प्राप्त करने पर भी डिसपोज़ किया जा सकता है - या आवश्यकतानुसार Dispose को आमंत्रित करने की आवश्यकता को समाप्त करें।

हैप्पी कोडिंग।


जब डिस्पोजेबल वस्तुओं इतना आसान कार्यक्षेत्रों से बाहर भी साथ काम कर - वस्तुओं उनके जीवनकाल के दौरान कई विभिन्न चर को सौंपा जा सकता है! - मुझे यह परिभाषित करना सबसे अच्छा लगता है कि कौन "नियंत्रण लेता है" जिसे मैं प्रलेखन में एनोटेट करता हूं। यदि ऑब्जेक्ट आजीवन अच्छी तरह से एक दायरे तक सीमित है तो using अच्छी तरह से काम करता है।

* एक स्थानीय चर स्वयं वस्तु को दृढ़ता से पहुंचने के लिए पर्याप्त रूप से पर्याप्त नहीं है क्योंकि यह संभव है कि परिवर्तनीय/असाइनमेंट आक्रामक रूप से ऑप्टिमाइज़ किया गया हो, यदि बाद में उसी दायरे से उपयोग नहीं किया जाता है। यह टाइमर की तरह वस्तुओं को पीड़ित कर सकता है।

+0

नियंत्रक को दस्तावेज करने पर धन्यवाद और महान युक्तियाँ! 'आक्रामक रूप से अनुकूलित' द्वारा आपका मतलब है 'obj a = new obj(); func (ए) 'को func (new obj()) में अनुकूलित किया जाएगा;'? – Dan7

+0

@ Dan7 कुछ जानकारी यहां मिल सकती है: http://msdn.microsoft.com/en-us/library/system.timers.timer.aspx चेतावनियों/उदाहरण उपयोग में। असल में इसका मतलब है कि जेआईटी जा सकता है: "आह हा! आप कभी भी उस चर का उपयोग कभी नहीं करते! इस प्रकार मैं इसे भूल सकता हूं (और जिस वस्तु का नाम है)" जो बदले में ऑब्जेक्ट को पुनः प्राप्त कर सकता है और शायद जीसी'एड इसके अलावा कोई और मजबूत संदर्भ नहीं रख रहा है। –

+4

चर का नाम * ऑब्जेक्ट * नहीं है। चर (जिनके नाम हैं) नाम * भंडारण स्थान *। स्टोरेज स्थानों में ऑब्जेक्ट्स के लिए * संदर्भ * होते हैं, यदि वेरिएबल संदर्भ प्रकार का है, या * ऑब्जेक्ट्स * है, तो चर वैल्यू प्रकार का है। बेशक सभी चरों के नाम नहीं हैं, और कुछ के कई नाम हैं। –

5

इस मामले आप एक स्लॉट/संदर्भ और एक IDisposable वस्तु के दो उदाहरणों है में। इन दोनों उदाहरणों को अनिश्चित रूप से निपटाया जाना चाहिए। कंपाइलर IDisposable के लिए कोई जादू नहीं डालता है। यह बस

को उदाहरण के संदर्भ बिंदु बदल जाएगा एक अच्छा पैटर्न होगा निम्नलिखित

using (thing = new DisposableThing()) { 
    // ... do stuff 
} 

thing = new DisposableThing(); 

आदर्श रूप में thing के दूसरे प्रयोग भी एक using ब्लॉक

1

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

ध्यान दें कि IDISposable का उद्देश्य वास्तव में किसी ऑब्जेक्ट को नष्ट करना नहीं है, बल्कि किसी ऑब्जेक्ट को देने के लिए जिसने पहले अन्य संस्थाओं से इसकी ओर से कुछ करने के लिए कहा है (उदाहरण के लिए एक जीडीआई हैंडल आरक्षित करें, विशेष रूप से उपयोग करें एक धारावाहिक बंदरगाह, आदि), उन संस्थाओं को सूचित करें कि उन्हें अब ऐसा करने की आवश्यकता नहीं है। अगर बाहरी संस्थाओं को कुछ भी नहीं बताता है कि उन्हें अब IDISposable ऑब्जेक्ट की ओर से कुछ करने की आवश्यकता नहीं है, तो वे इसे जारी रखेंगे - भले ही वे ऑब्जेक्ट कर रहे हों, अब यह मौजूद नहीं है।

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