जवाबों:
जैसा कि कई अन्य लोगों ने सामान्य रूप से बताया है कि यह कोई समस्या नहीं है।
एकमात्र ऐसा मामला जिसके कारण आप समस्याएँ उत्पन्न करेंगे, यदि आप एक उपयोग कथन के बीच में लौटते हैं और इसके अतिरिक्त चर का उपयोग करते हुए लौटते हैं। लेकिन तब फिर से, यह आपके मुद्दों को भी पैदा करेगा भले ही आप वापस नहीं आए और बस एक चर का संदर्भ रखा।
using ( var x = new Something() ) {
// not a good idea
return x;
}
बस उतना ही बुरा
Something y;
using ( var x = new Something() ) {
y = x;
}
return
बयान using
किसी भी कोड पथ द्वारा ब्लॉक के अंत को दुर्गम बनाता है । using
ब्लॉक के अंत को चलाने की जरूरत है ताकि वस्तु को जरूरत पड़ने पर निपटाया जा सके।
यह पूरी तरह से ठीक है।
आप स्पष्ट रूप से यही सोच रहे हैं
using (IDisposable disposable = GetSomeDisposable())
{
//.....
//......
return Stg();
}
आँख बंद करके अनुवाद किया जाता है:
IDisposable disposable = GetSomeDisposable()
//.....
//......
return Stg();
disposable.Dispose();
जो, बेशक, एक समस्या होगी, और using
बयान को व्यर्थ बना देगा --- यही वजह है कि यह ऐसा नहीं करता है।
कंपाइलर यह सुनिश्चित करता है कि ब्लॉक को छोड़ने से पहले ऑब्जेक्ट का निपटान किया जाता है - यह ब्लॉक को कैसे छोड़ता है, इसकी परवाह किए बिना।
यह बिल्कुल ठीक है - कोई समस्या नहीं है। आप क्यों मानते हैं कि यह गलत है?
एक प्रयोग बयान एक कोशिश / अंत में ब्लॉक के लिए बस चीनी है, और के रूप में Grzenio कहते हैं कि यह भी एक कोशिश ब्लॉक से लौटने के लिए ठीक है।
वापसी की अभिव्यक्ति का मूल्यांकन किया जाएगा, फिर अंत में ब्लॉक निष्पादित किया जाएगा, फिर विधि वापस आ जाएगी।
यह पूरी तरह से स्वीकार्य है। एक का उपयोग कर बयान IDisposable वस्तु कोई बात नहीं क्या निपटारा किया जाएगा सुनिश्चित करता है।
से MSDN :
उपयोग कथन यह सुनिश्चित करता है कि आप ऑब्जेक्ट पर विधियों को कॉल करते समय भी अपवाद कहते हैं। आप एक कोशिश ब्लॉक के अंदर वस्तु डालकर और फिर अंततः ब्लॉक में डिस्पोज को बुलाकर एक ही परिणाम प्राप्त कर सकते हैं; वास्तव में, यह है कि कंपाइलर द्वारा उपयोग किए गए कथन का अनुवाद कैसे किया जाता है।
कोड बलो दिखाता है कि कैसे using
काम कर रहा है:
private class TestClass : IDisposable
{
private readonly string id;
public TestClass(string id)
{
Console.WriteLine("'{0}' is created.", id);
this.id = id;
}
public void Dispose()
{
Console.WriteLine("'{0}' is disposed.", id);
}
public override string ToString()
{
return id;
}
}
private static TestClass TestUsingClose()
{
using (var t1 = new TestClass("t1"))
{
using (var t2 = new TestClass("t2"))
{
using (var t3 = new TestClass("t3"))
{
return new TestClass(String.Format("Created from {0}, {1}, {2}", t1, t2, t3));
}
}
}
}
[TestMethod]
public void Test()
{
Assert.AreEqual("Created from t1, t2, t3", TestUsingClose().ToString());
}
आउटपुट:
't1' बनाया गया है।
't2' बनाया गया है।
't3' बनाया गया है।
'T1, t2, t3 से निर्मित' बनाया गया है।
't3' का निस्तारण किया जाता है।
't2' का निस्तारण किया जाता है।
't1' का निस्तारण किया जाता है।
निपटाने को वापसी के बयान के बाद बुलाया जाता है, लेकिन फ़ंक्शन के बाहर निकलने से पहले।
शायद यह 100% सच नहीं है कि यह स्वीकार्य है ...
यदि आप घोंसले के शिकार होने और एक नेस्टेड के भीतर से लौटने वाले होते हैं, तो यह सुरक्षित नहीं हो सकता है।
इसे एक उदाहरण के रूप में लें:
using (var memoryStream = new MemoryStream())
{
using (var textwriter = new StreamWriter(memoryStream))
{
using (var csv = new CsvWriter(textwriter))
{
//..write some stuff to the stream using the CsvWriter
return memoryStream.ToArray();
}
}
}
मैं एक DataTable में सीएसवी के रूप में आउटपुट किया जा रहा था। बीच में वापसी के साथ, यह सभी पंक्तियों को स्ट्रीम में लिख रहा था, लेकिन आउटपुट सीएसवी हमेशा एक पंक्ति (या एकाधिक, बफर के आकार के आधार पर) को याद कर रहा था। इसने मुझे बताया कि कुछ ठीक से बंद नहीं किया जा रहा था।
सही तरीका यह सुनिश्चित करना है कि पिछले सभी उपयोगों को ठीक से निपटाया जाए:
using (var memoryStream = new MemoryStream())
{
using (var textwriter = new StreamWriter(memoryStream))
{
using (var csv = new CsvWriter(textwriter))
{
//..write some stuff to the stream using the CsvWriter
}
}
return memoryStream.ToArray();
}