2016-11-28 11 views
5

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

ऐसा लगता है कि प्रत्येक संपत्ति और विधि में सेटर की शुरुआत में कोड की एक पंक्ति है और गेटटर उस अपवाद को फेंकने के लिए भी है, यहां तक ​​कि यह सिर्फ ThrowIfDisposed() है। यदि आपके पास 40 गुण हैं जो 80 बार दोहराई गई रेखाएं हैं। एक बड़ी कक्षा में यह बहुत तेजी से जोड़ सकता है।

मैं एक बेहतर तरीका नहीं ढूंढ पाया है, ऐसा लगता है कि यह वही तरीका है, लेकिन मैंने सोचा कि मैं पूछूंगा। क्या कोई बेहतर तरीका है?

+0

डिस्पोजेबल पैटर्न एक .NET 1.x गलती थी, इससे छुटकारा पाने में बहुत मुश्किल थी। सेफहैंडल कक्षाओं में लागू महत्वपूर्ण फाइनल के साथ .NET 2.0 में पूरी तरह से तय किया गया। पैटर्न के लिए एकमात्र शेष उपयोग तब होता है जब बेस क्लास इसे लागू करता है, जिससे आप इससे निपटने के लिए मजबूर हो जाते हैं। फेंकने के साथ अपने कोड को मिर्च करने से यह बेहतर नहीं होता है, आप बस अपवाद फेंकने के लिए बेस क्लास पर भरोसा करते हैं। –

+0

आपकी टिप्पणियों के लिए धन्यवाद। मुझे सेफहैंडल क्लास में देखना होगा। मुझे डिस्पोजेबल पैटर्न कभी पसंद नहीं आया और बेहतर प्रतिस्थापन ढूंढना अच्छा लगेगा। – JHJ

उत्तर

7

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

public class MyStream : IDisposable 
{ 
    private string name; 
    private Stream stream; 

    public MyStream(string name) 
    { 
     this.Name = name; 
     this.Stream = new FileStream(...); 
    } 

    public string Name 
    { 
     get 
     { 
      return this.name; 
     } 
    } 

    public Stream Stream 
    { 
     get 
     { 
      if (this.IsDisposed) 
      { 
       throw new ObjectDisposedException(); 
      } 

      return this.stream; 
     } 
    } 

    private bool IsDisposed { get; set; } 

    public void Dispose() 
    { 
     if (!this.IsDisposed) 
     { 
      this.IsDisposed = true; 
      this.Stream.Dispose(); 
      this.Stream = null; 
     } 
    } 
} 

यहाँ, संपत्ति Stream एक अपवाद फेंकता है, तो यह अब और नहीं किया जा सकता। लेकिन Name में फेंकने का कोई कारण नहीं है। वहाँ से, कई मामलों में, आप अपने कोड तो वास्तविक समस्या पैदा करने वाले संपत्ति तक पहुँच अपवाद फेंकता गुणनखंड कर सकते हैं:

public int Length 
{ 
    get 
    { 
     // Since we access the Stream property, the ObjectDisposedException 
     // will be thrown when the class is disposed 
     return this.Stream.Length; 
    } 
} 

आप अभी भी इस पद्धति का अनुसरण करते हुए भी सजाने के लिए भी कई गुण होते हैं, तो आप Fody जैसे पुस्तकालयों का उपयोग कर सकते हैं जो आपको संकलन समय पर एक व्यवहार को इंजेक्ट करने की अनुमति देता है। इसका उपयोग करके, आप एक विशेषता [ThrowIfDisposed] बना सकते हैं जिसे आप आवश्यकतानुसार गुणों पर लागू करते हैं।

+1

मैं मानता हूं कि 40+ गुण बहुत अधिक हैं और आम तौर पर इसका मतलब है कि एक ही कक्षा में पैक किया जाना चाहिए जिसे तोड़ा जाना चाहिए लेकिन कभी-कभी यह एकमात्र तरीका है। एक्सेल एक उदाहरण है। इसके साथ काम करना मुझे इस सवाल से पूछने के लिए प्रेरित करता है। उदाहरण के लिए, रेंज क्लास में 99 गुण और 87 विधियां हैं। .NET से COM के साथ काम करना ** में दर्द है। एक बार ऑब्जेक्ट का निपटारा हो जाने के बाद और एक्सेल का उपयोग करने वाले किसी भी गुण या विधियों को मुक्त करने के लिए सभी एक्सेल संसाधनों ने शून्य सूचक अपवाद फेंक दिया। यह सुरुचिपूर्ण प्रतीत होता है लेकिन हो सकता है कि सिर्फ उन शून्य सूचक अपवादों को इस मामले में समाधान दें। – JHJ

0

चेक अन्य विषय: Handling ObjectDisposedException correctly in an IDisposable class hierarchy

आप अपवाद वर्ग कि :IDisposable लागू करता है की हर बार किसी को पहुँच संपत्ति फेंक की जरूरत नहीं है। यह केवल जरूरी है, यदि आप उस ऑब्जेक्ट तक पहुंच रहे हैं जिसे निपटान किया जाना चाहिए (उदा। फाइलों को लिखना/पढ़ना, नेटवर्क सॉकेट एक्सेस करना ..)। अन्य सभी मामलों के लिए, आप सामान्य कक्षा के विचार के साथ जा सकते हैं।

आम तौर पर वस्तुओं/कक्षाओं में इस बड़ी संख्या में गुण नहीं होते हैं क्योंकि उन्हें अधिक कक्षाओं के बीच विभाजित करने का विकल्प होता है -> जो आपको इस :IDisposable का केवल एक हिस्सा बनाने की अनुमति देगा, और बाकी IDisposable पर स्वतंत्र होंगे कक्षा।

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