मेरे पास इस तरह के कई वर्ग हैं - और मेरी सिफारिश है जब भी संभव हो कक्षा को सील कर दें। IDisposable
+ विरासत काम कर सकती है, लेकिन 99% बार आपको इसकी आवश्यकता नहीं है - और इसमें गलतियों को करना आसान है।
जब तक आप एक सार्वजनिक एपीआई नहीं लिख रहे हैं (इस मामले में लोगों को आपके कोड को लागू करने की अनुमति देना अच्छा होता है, हालांकि वे चाहते हैं - यानी IDisposable
का उपयोग करने के लिए), आपको इसका समर्थन करने की आवश्यकता नहीं है।
सिर्फ कार्य करें:
public sealed class Foo : IDisposable
{
private StreamWriter _Writer;
public Foo(string path)
{
FileStream fileWrite = File.Open (path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite);
try {
_Writer = new StreamWriter (fileWrite, new ASCIIEncoding());
} catch {
fileWrite.Dispose();
throw;
}
}
public void Dispose()
{
_Writer.Dispose();
}
}
नोट कोशिश ... पकड़ने; तकनीकी रूप से StreamWriter
कन्स्ट्रक्टर अपवाद फेंक सकता है, इस मामले में यह FileStream
का स्वामित्व कभी नहीं लेता है और आपको इसे स्वयं निपटाना होगा।
यदि आप वास्तव में कई IDisposable
एस का उपयोग कर रहे हैं, तो उस कोड को C++/CLI में डालने पर विचार करें: जो आपके लिए वह बॉयलरप्लेट कोड बनाता है (यह पारदर्शी रूप से मूल और प्रबंधित वस्तुओं दोनों के लिए उचित निर्धारक विनाश तकनीक का उपयोग करता है)।
विकिपीडिया सी के लिए एक सभ्य IDisposable नमूना है ++ (वास्तव में, यदि आप कई IDisposable का है, सी ++ वास्तव में ज्यादा सरल से सी # है): Wikipedia: C++/CLI Finalizers and automatic variables।
उदाहरण के लिए, C++/CLI में एक "सुरक्षित" डिस्पोजेबल कंटेनर को लागू करने की तरह दिखता है ...
public ref class MyDisposableContainer
{
auto_handle<IDisposable> kidObj;
auto_handle<IDisposable> kidObj2;
public:
MyDisposableContainer(IDisposable^ a,IDisposable^ b)
: kidObj(a), kidObj2(b)
{
Console::WriteLine("look ma, no destructor!");
}
};
इस कोड को सही ढंग से भी एक कस्टम IDisposable कार्यान्वयन जोड़े बिना kidObj और kidObj2 निपटाने जाएगा, और यह करने के लिए मजबूत है अपवादों को या तो कार्यान्वयन का निपटान (ऐसा नहीं होना चाहिए, लेकिन अभी भी), और IDisposable
सदस्यों या मूल संसाधनों के चेहरे में बनाए रखने के लिए सरल है।
नहीं कि मैं सी ++/सीएलआई का एक बड़ा प्रशंसक हूं, लेकिन भारी संसाधन-उन्मुख कोड के लिए इसे सी # आसानी से हराया गया है, और इसमें प्रबंधित और देशी कोड दोनों के साथ बिल्कुल शानदार इंटरऑप है - संक्षेप में, सही गोंद कोड में; -)। मैं सी # में अपने कोड का 9 0% लिखता हूं, लेकिन सभी इंटरऑप जरूरतों के लिए सी ++/सीएलआई का उपयोग करता हूं (esp। अगर आप किसी भी Win32 फ़ंक्शन को कॉल करना चाहते हैं - मार्शलए और अन्य जगहों पर अन्य इंटरऑप विशेषताएं भयानक और पूरी तरह से समझ में नहीं आती हैं)।
जांचना और यह सुनिश्चित करना न भूलें कि अस्वीकरण कॉल करने से पहले _Writer गैर-शून्य है। आपका निपटान एकाधिक कॉल w/o विफलता को सहन करने में सक्षम होना चाहिए। – user7116
दरअसल वह पहले _Disposed जांचता है, तो यह ठीक है (हालांकि थ्रेड-सुरक्षित नहीं है)। –
@mafutrct: अद्यतन उत्तर उपलब्ध है। – AnthonyWJones