我最近正在阅读一篇垃圾收集文章,并决定一起玩并尝试获得更深入的理解。我编写了以下代码,尝试使用 using
语句,但对结果感到惊讶......我预计 using block 之外的 e.Parent.Name 会变成 ka-blooey。
这里到底发生了什么?
static void Main(string[] args)
{
Employee e = new Employee();
using (Parent p = new Parent())
{
p.Name = "Betsy";
e.Parent = p;
Console.WriteLine(e.Parent.Name);
}
Console.WriteLine(e.Parent.Name);
Console.ReadLine();
}
public class Employee
{
public Parent Parent;
}
public class Parent : IDisposable
{
public string Name;
public void Dispose()
{
Console.WriteLine("Disposing Parent");
}
}
最佳答案
您的 Dispose 方法实际上不会对 Parent
的实例执行任何操作,因此它仍然是公平的游戏/作为类的可用实例工作。
IDisposable
通常在您的类持有非托管资源(例如数据库连接或文件)时使用,以便在 Dispose()
时可以将其清除叫做。仅调用 Dispose
不会对非托管资源执行任何操作,方法中必须有一些代码对这些资源执行某些操作。虽然 c# 可能具有 using() {}
语法来将 IDisposable
对象的实例化和处置包装在 try/catch/finally 中,但这并不意味着它会执行任何操作“特殊”与处置对象。
假设,Name
实际上是一个非托管资源,而不仅仅是一个字符串,您的 Dispose()
方法可以读取:
public void Dispose()
{
Name = null;
Console.WriteLine("Disposing Parent");
}
因为您已将 p
分配给 e.Parent
,对象本身仍然“在范围内”,因为有对它的引用,因此它仍然可以访问 Console.WriteLine(e.Parent.Name);
从中生成输出。
目前“CLR 周”也在 The Old New Thing 结束了本周的前 3 篇文章讨论了垃圾收集器及其工作/行为方式。它们非常值得一读:
关于关于范围的 C# 内存分配/取消分配问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3453446/