2009-10-08 8 views
7

आप के रूप में एक ब्रश और कलम है:डिस्पोजेबल ऑब्जेक्ट्स को कैसे प्रबंधित करें हमारे पास कोई संदर्भ नहीं है?

Brush b = new SolidBrush(color); 
Pen p = new Pen(b); 

और उन्हें इतनी तरह निपटाने:

b.Dispose(); 
p.Dispose(); 

आप इसे कैसे निपटान होगा अगर यह था:

Pen p = CreatePenFromColor(color) बनाना होगा जो आपके लिए ब्रश और कलम? मैं इस विधि के अंदर ब्रश का निपटान नहीं कर सकता, है ना?

क्या यह एक तरीका है जो डिस्पोजेबल ऑब्जेक्ट्स के साथ उपयोग नहीं किया जा सकता है?

संपादित करें: मेरा मतलब क्या है, आप ब्रश का निपटान कैसे करते हैं?

+0

o.o मुझे नहीं पता था कि ब्रश और कलम कार्यान्वित IDisposable ... –

+0

lol, यह निश्चित रूप से करता है। –

+0

लेकिन यह ब्रश वास्तव में संदर्भित कहां है? क्यों (और कहां) आप इसे बना रहे हैं यदि आप केवल विधि परिणाम के रूप में पेन लौट रहे हैं? – Groo

उत्तर

9

यह ब्रश इंस्टेंस का निपटान करने के लिए CreatePenFromColor विधि का काम है।यह एक नज़र में स्पष्ट नहीं है लेकिन यदि आप पेन क्लास के कार्यान्वयन में खोदते हैं तो आप देखेंगे कि यह ब्रश इंस्टेंस में पारित नहीं होता है। इसके बजाय यह कुछ मानों की गणना करने के लिए इसका उपयोग करता है। इसलिए ब्रश इंस्टेंस को CreatePenFromColor पर कॉल से परे रहने का कोई कारण नहीं है और विधि को उदाहरण का निपटान करना चाहिए।

+0

धन्यवाद जेरेड, मुझे यह नहीं पता था। –

+0

यह जरूरी नहीं है कि यह सच है। पेन कन्स्ट्रक्टर ब्रश के हैंडल को 'GdipCreatePen2' पर पास करता है। मुझे नहीं पता कि 'GdipCreatePen2' को जीवित रहने के लिए ब्रश की आवश्यकता है (फ़ंक्शन को शायद ही कभी दस्तावेज किया गया है), लेकिन मुझे लगता है कि यह करता है।याद रखें कि ब्रश एक छवि के साथ 'बनावट ब्रश' हो सकता है, और आप नहीं चाहते कि पेन स्मृति में छवि की एक अलग प्रतिलिपि बनाये ताकि आप ब्रश का निपटान कर सकें। – SLaks

+1

@ स्लक्स, GdipCreatePen2 AFAIK को जीवित रहने की आवश्यकता नहीं है। मैंने बहुत सीमित दस्तावेज के माध्यम से खोद दिया और इसे केवल पेन को स्थापित करने की आवश्यकता है, इसे बनाए रखने के लिए नहीं। – JaredPar

6

जब भी आप पूरा कर लेंगे तब भी आपको इसका निपटान करना होगा।

उदाहरण के लिए, आप इसे इस तरह कह सकते हैं: एक विधि एक IDisposable ऑब्जेक्ट

using (Pen p = CreatePenFromColor(color)) 
{ 
    // do something 
} 

, तो इसे निपटाने के लिए अपने कर्तव्य है।

[संपादित करें] अब मुझे प्रश्न मिला - आप पेन (ब्रश बी) कन्स्ट्रक्टर का उपयोग कर रहे हैं।

ए।

public Pen CreatePenFromColor(Color c) 
{ 
    using (Brush b = new SolidBrush(c)) 
    { return new Pen(b); } 
} 

ख: इस मामले में, यह है कि पेन तो अपने विधि ऐसा दिखाई दे सकता, निर्माता के बाद ब्रश उदाहरण की जरूरत नहीं है लगता है। क्यों न केवल Pen(Color color) का उपयोग करें?

public Pen CreatePenFromColor(Color c) 
{ 
    return new Pen(c); 
} 

सी। (टिप्पणी के बारे में) यदि पेन आंतरिक रूप से ब्रश का संदर्भ रखेगा, तो आप पेन के साथ समाप्त होने से पहले इसे निपटाने में सक्षम नहीं होंगे।

public class PenHelper : IDisposable 
{ 
    private readonly Brush _brush; 
    public PenHelper(Color color) 
    { 
     _brush = new SolidBrush(color); 
    } 

    public Pen CreatePen() 
    { 
     return new Pen(_brush); 
    } 

    public void Dispose() 
    { 
     _brush.Dispose(); 
    } 
} 

और उसके बाद इस तरह इसका इस्तेमाल:

using (PenHelper penHelper = new PenHelper(Color.Black)) 
{ 
    using (Pen pen = penHelper.CreatePen()) 
    { 
      // do stuff 
    } 
} 

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

+0

+1 "लोग पेन बनाने के लिए ब्रश क्यों बना रहे हैं?!" –

+0

धन्यवाद। उदाहरण में आप, ब्रश बी को जल्द ही पेन्स वापस लौटाया जाएगा, ठीक है? यदि पेन के अंदर ब्रश करने का संदर्भ था, तो यह एक उदाहरण फेंक देगा? बस सोच रहा। विस्तारित उदाहरण के लिए –

+0

धन्यवाद। –

0

जब कोई विधि एक आईडीस्पोजेबल उदाहरण से हाथ रखती है, तो यह एक साथ जीवनभर प्रबंधन जिम्मेदारी को सौंपती है।

अब उपयोग के बाद ऑब्जेक्ट का निपटान करने के लिए कॉलर की जिम्मेदारी है। यदि उस ऑब्जेक्ट में अन्य आईडीस्पोजेबल ऑब्जेक्ट्स हैं, तो सम्मेलन द्वारा हमें कंटेनर को अपने बच्चों का निपटान करने की अपेक्षा करनी चाहिए जब हम इसका निपटान करते हैं - अन्यथा यह कंटेनर में एक बग का संकेत देगा।

अपने ठोस उदाहरण में, आपको पेन को अपने आंतरिक ब्रश इंस्टेंस का निपटान करने की अपेक्षा करनी चाहिए जब आप इसका निपटान करते हैं।

+0

रंग भी डिस्पोजेबल हैं? –

+1

नहीं, रंग एक संरचना है। – Groo

+1

@ जोन वेंग: 'टाइपो' - मैंने इसे आपकी टिप्पणी के साथ समवर्ती रूप से सही किया ... –

2

आपकी समस्या का कोई सामान्य समाधान नहीं है।

अपने विशिष्ट उदाहरण में, यह कोई समस्या नहीं है, क्योंकि पेन में एक कन्स्ट्रक्टर है जो सीधे रंग लेता है।

कुछ कक्षाएं अपने कन्स्ट्रक्टर पैरामीटर स्वयं (विशेष रूप से स्ट्रीम-संबंधित कक्षाएं) का निपटान करेंगे; प्रतिबिंब में प्रत्येक वर्ग की जांच करें।

वर्ग आप घटक से विरासत में मिली लौट रहे हैं, तो आप अपने निपटाई गई घटना के लिए कोई हैंडलर जोड़ सकते हैं।

वर्ग आप वापस लौट रहे हैं सील नहीं है, तो आप एक विरासत संस्करण है कि वस्तु आप के साथ-साथ वो बना disposes बना सकते हैं।

अंत में, यदि आप वास्तव में चाहते थे, तो आप एक आवरण वर्ग कि वस्तु आप के लिए लौट रहे हैं और निर्माता पैरामीटर disposes बना सकते हैं। हालांकि, यह बहुत भ्रमित होगा और मैं इसकी अनुशंसा नहीं करता।

+0

धन्यवाद, मुझे नहीं पता था कि पेन सीधे रंग ले सकता है। यह मजाकिया है क्योंकि मुझे ब्रश और कलम को अलग-अलग बनाने और फिर पेंटिंग के लिए पेन का उपयोग करने वाले कोड का बहुत कुछ दिखाई देता है। –

+0

फिर आपको यह जवाब स्वीकार करना चाहिए। – SLaks

+0

हाँ, यह करता है। इसके लिए सिर्फ एक साफ सामान्य समाधान नहीं है। – SLaks

1

ग्राफिक्स से संबंधित वर्गों में से कई के साथ मेरी peeves में से एक इस तरह के मुद्दों से निपटने के लिए कोई सुसंगत पैटर्न है कि वहाँ है। आंशिक संदर्भ गिनती को लागू करने का साधन वास्तव में आवश्यक है। COM शैली में नहीं, जहां संदर्भों के चारों ओर गुज़रने के लिए संदर्भ संख्याओं के निरंतर बंपिंग की आवश्यकता होती है, लेकिन एक माध्यम से, एक आईडीस्पोजेबल ग्राफिक्स ऑब्जेक्ट दिया जाता है, कोई अन्य उदाहरण का अनुरोध कर सकता है जो समान अंतर्निहित संसाधन साझा करता है। संसाधनों को संदर्भित काउंटर के साथ साझा ऑब्जेक्ट में स्वयं encapsulated किया जाएगा। एक और संदर्भ उदाहरण बनाना काउंटर में वृद्धि करेगा; कॉलिंग एक संदर्भ उदाहरण पर निपटान इसे कम करेगा। लाभ के 99% को बनाए रखते हुए, यह संदर्भ गणना के 95% ओवरहेड से बच जाएगा।

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