উত্তর:
অন্য বেশিরভাগ সাধারণভাবে উল্লেখ করেছেন যে এটি কোনও সমস্যা নয়।
আপনি যদি কোনও ব্যবহারের বিবৃতিটির মাঝামাঝি ফিরে আসেন এবং অতিরিক্তভাবে ভেরিয়েবলটি ব্যবহার করে ইনটি ফিরিয়ে দেন তবে এটি কেবল আপনার ক্ষেত্রে সমস্যা সৃষ্টি করবে। তবে আবার, আপনি ফিরে না এসে এমনকি কেবল একটি ভেরিয়েবলের রেফারেন্স রাখলেও এটি আপনাকে সমস্যা সৃষ্টি করবে।
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
যার কারণে যে বিবৃতি বরং অর্থহীন --- না এটা কি করে।
সংকলকটি নিশ্চিত করে যে নিয়ন্ত্রণটি ব্লকটি ছাড়ার আগে অবজেক্টটি নিষ্পত্তি হয়ে যায় - এটি ব্লকটি কীভাবে ছাড়বে তা নির্বিশেষে।
এটি একেবারে ঠিক - কোনও সমস্যা নেই। কেন আপনি ভুল বিশ্বাস করেন?
একটি ব্যবহারের বিবৃতিটি চেষ্টা / অবশেষে ব্লকের জন্য কেবল সিনট্যাকটিক চিনি এবং গ্রাজনিও যেমন বলেছে তবে চেষ্টা ব্লক থেকেও ফিরে আসাই ভাল fine
রিটার্ন এক্সপ্রেশন মূল্যায়ন করা হবে, তারপরে অবশেষে ব্লকটি কার্যকর করা হবে, তারপরে পদ্ধতিটি ফিরে আসবে।
এটি সম্পূর্ণ গ্রহণযোগ্য। একটি ব্যবহারের বিবৃতি নিশ্চিত করে যে আইডিস্পোজযোগ্য বস্তুটি যাই হোক না কেন নিষ্পত্তি হবে।
এমএসডিএন থেকে :
ব্যবহারের বিবৃতিটি নিশ্চিত করে যে ডিসপোজ বলা হয় এমনকি যদি আপনি কোনও বস্তুটিতে পদ্ধতি কল করার সময় কোনও ব্যতিক্রম ঘটে। আপনি চেষ্টাটি ব্লকের ভিতরে অবজেক্টটি স্থাপন করে এবং পরে ডিসপোজকে শেষ অবধি কল করে একই ফলাফল অর্জন করতে পারেন; প্রকৃতপক্ষে, কম্পাইলার দ্বারা এভাবেই ব্যবহারের বিবৃতিটি অনুবাদ করা হয়।
কোড বেলো দেখায় যে কীভাবে 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' তৈরি হয়।
'টি 1, টি 2, টি 3 থেকে তৈরি' তৈরি হয়।
't3' নিষ্পত্তি করা হয়।
'টি 2' নিষ্পত্তি করা হয়।
'টি 1' নিষ্পত্তি করা হয়।
নিষ্পত্তি ফিরতি বিবৃতি পরে বলা হয় কিন্তু ফাংশন থেকে প্রস্থান আগে।
সম্ভবত এটি 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();
}
}
}
আমি সিএসভি হিসাবে আউটপুট হওয়ার জন্য একটি ডেটা টেবিল দিয়ে যাচ্ছিলাম। মাঝখানে ফিরে আসার সাথে সাথে, এটি স্রোতে সমস্ত সারি লিখছিল, তবে আউটপুটযুক্ত সিএসভি সর্বদা একটি সারি (বা একাধিক, বাফারের আকারের উপর নির্ভর করে) হারিয়েছিল। এটি আমাকে জানিয়েছিল যে কিছু সঠিকভাবে বন্ধ করা হচ্ছে না।
পূর্ববর্তী সমস্ত ব্যবহার সঠিকভাবে নিষ্পত্তি হয়েছে তা নিশ্চিত করা সঠিক উপায়:
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();
}