int number = 10; // روی Stack ذخیره میشود
Person person = new Person(); // شیء جدید در Heap ساخته میشود
void CreateObjects()
{
// شیء جدید در هیپ ساخته میشود
Person person1 = new Person();
// ارجاع جدید به همان شیء
Person person2 = person1;
// حالا person1 را null میکنیم، اما شیء هنوز در حافظه است (چون person2 ارجاع دارد)
person1 = null;
// حالا person2 هم null میشود، شیء دیگر ارجاعی ندارد
person2 = null;
// حالا GC میتواند این شیء را پاک کند (البته نه لزوماً بلافاصله!)
}
public interface IDisposable
{
void Dispose();
}
هر کلاسی که این اینترفیس را پیادهسازی کند، باید منابع غیرمدیریتشده را در Dispose آزاد کند.
using (FileStream file = File.Open("test.txt", FileMode.Open))
{
// کار با فایل
} // اینجا به طور خودکار file.Dispose() فراخوانی میشود، حتی اگر خطایی رخ دهد!
یا به صورت دستی:
FileStream file = null;
try
{
file = File.Open("test.txt", FileMode.Open);
// کار با فایل
}
finally
{
file?.Dispose(); // مطمئن میشویم فایل حتما بسته میشود
}
using (var resource = new SomeDisposableResource())
{
// کار با resource
} // اینجا Dispose() به صورت خودکار فراخوانی میشود
کامپایلر C# آن را به این شکل تبدیل میکند:
var resource = new SomeDisposableResource();
try
{
// کار با resource
}
finally
{
resource.Dispose(); // حتی اگر خطا رخ دهد، Dispose فراخوانی میشود
}
نکات کلیدی درباره using:
using (var file = File.OpenRead("data.txt"))
using (var reader = new StreamReader(file))
{
string content = reader.ReadToEnd();
} // اول reader.Dispose() و سپس file.Dispose() فراخوانی میشود