2015-10-12 7 views
6
के लिए अपरिवर्तनीय का उपयोग

निम्नलिखित IDisposable वर्ग पर विचार करें:,IDisposable

class MyClass : IDisposable 
{ 
    public bool IsDisposed { get; private set; } = false; 

    public void Dispose() 
    { 
     IsDisposed = true; 
    } 
} 

इस वर्ग में हर विधि, Dispose() सहित इस तरह एक चेक के साथ शुरू करना चाहिए:

if (IsDisposed) 
{ 
    throw new ObjectDisposedException(...); 
} 

चूंकि यह थकाऊ और दोहराव है इसे सभी तरीकों से लिखने के लिए, मैं अनुबंध invariant का उपयोग करना चाहता हूं:

public class MyClass : IDisposable 
{ 
    ... 

    [ContractInvariantMethod] 
    private void objectInvariant() 
    { 
     Contract.Invariant(!IsDisposed) 
    } 

    ... 
} 

हालांकि, यह केवल यह सुनिश्चित करता है IsDisposed झूठी अंत प्रत्येक सार्वजनिक विधि के, Dispose() को छोड़कर पर है।

एक बार Dispose() कहा जाता है, की जांच प्रत्येक विधि की शुरुआत में किया जाना चाहिए (Dispose() सहित)। अन्यथा विधि चलाने के दौरान ओबेजेक्ट अमान्य स्थिति में होगा, संभावित रूप से कठिन बग की ओर अग्रसर होगा।

इसलिए अनुबंध अपरिवर्तनशीलताओं IDisposable के लिए वास्तव में प्रयोग करने योग्य नहीं हैं। या क्या मैं कुछ न कुछ भूल रहा हूं?

क्या आविष्कारों को पूर्व शर्त के रूप में भी इस्तेमाल किया जा सकता है या क्या मुझे वास्तव में सभी विधियों के लिए एक ही पूर्व शर्त (!IsDisposed) लिखना है?

+4

"निपटान() सहित इस वर्ग में प्रत्येक विधि को इस तरह की जांच से शुरू होना चाहिए" - निपटान विधि को आम तौर पर फेंकने के बिना कई बार बुलाया जाना चाहिए, इसलिए इस चेक को शामिल नहीं किया जाना चाहिए। साथ ही सदस्यों में यह चेक करना आम बात है जिसका उपयोग ऑब्जेक्ट के निपटारे के बाद नहीं किया जा सकता है - अन्य सदस्यों को चेक की आवश्यकता नहीं है। – Joe

+0

इस प्रश्न को भी देखें। मुझे लगता है कि यह सहायक हो सकता है। http://stackoverflow.com/questions/9192709/run-a-method-before-all-methods-of-a-class सवाल यह है कि उस वर्ग में anymethod कॉल करने से पहले एक विधि कॉल करने के बारे में है। और शायद इस सवाल का जवाब http://stackoverflow.com/a/9192747/4767498 –

उत्तर

4

आप अपरिवर्तनशीलताओं गलतफहमी हो रहे हैं। प्रलेखन से:

वस्तु अपरिवर्तनशीलताओं की स्थिति है कि एक वर्ग के प्रत्येक उदाहरण के लिए सच होना चाहिए जब भी उस वस्तु एक ग्राहक को दिखाई देता है कर रहे हैं।

(जोर मेरा) आपका वस्तु बहुत अच्छी तरह से करने के बाद आप Dispose कहा जाता है, वस्तु "अवैध" बनाने एक ग्राहक को दिखाई हो सकता है। लेकिन यह वास्तव में आपके ऑब्जेक्ट के लिए IsDisposed == true के लिए एक मान्य स्थिति है।

आप वास्तव में पूर्व शर्तों के लिए देख रहे हैं।

+0

अच्छा। मैं मूल रूप से हर एक विधि और संपत्ति के लिए वही पूर्व शर्त लगाने से बचने के लिए एक रास्ता तलाश रहा हूं। – Libor

+1

यह पोस्टशर्प जैसे एओपी लाइब्रेरी का काम होगा। आप LinFu का उपयोग करके गतिशील इंटरसेप्टर भी बना सकते हैं। –

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