我正在努力了解处理对象和垃圾收集。特别是,我不明白为什么我仍然可以使用处置对象。我实际上并没有尝试做任何事情,我现在只是在玩理论,在我的理解中,我认为我无法做到以下几点:
class Program
{
static void Main(string[] args)
{
Person p = new Person();
using (p)
{
p.Name = "I am Name";
}
Console.WriteLine(p.Name); // I thought this would break because I've already disposed of p
Console.ReadLine();
}
}
public class Person : IDisposable
{
public string Name;
public void Dispose()
{
Console.WriteLine("I got killed...");
}
}
我希望有人可以在这里给我一些指导或指导,以便澄清我对这个概念的误解?
答案 0 :(得分:7)
处理对象并没有做任何神奇的事情 - CLR根本不关心IDisposable
......它只是一个在C#中有支持的框架接口(和其他语言)。调用Dispose
就像调用其他方法一样。
如果您在执行进一步操作时没有生成配置对象失败,则不会失败。实际上,在某些情况下,您确实想要能够 - 例如,在ToArray
上调用MemoryStream
之后,即使您处置了Read
也没问题。无法调用MemoryStream
等。对于MemoryStream
的写入是从包含def translate(self, delta_x, delta_y):
if not isinstance(delta_x, float):
的包装器链接的情况下,这可能非常方便,但是你想要之后的数据。
一般情况下,您应该编码,好像您可以在处置后使用已处置的对象,除非您确定它仍然支持您需要的操作。默认位置"我预计会破坏..."是安全的。
答案 1 :(得分:4)
当您拥有使用非托管资源的对象时,将使用Dispose模式,该对象需要在不再需要时释放。 GC自动释放托管资源。
在您的示例中,字符串Name是受管资源。如果那里有一个打开的文件,那将是一个非托管资源。然后,Dispose方法将关闭关闭文件句柄,这将使对象的文件访问在Dispose之后不可用。然而,你可以要求提供名称,因为在GC收集该对象之前,它将存在。
推荐阅读:MSDN Dispose Pattern
答案 2 :(得分:1)
IDisposable
是处理托管代码中的非托管资源的惯例。
您正在实施IDisposable
界面,稍后您只是进行Dispose()
方法调用,而不是破坏或查杀实际对象
什么是非托管资源?
非托管资源是垃圾收集器无法收集的资源。例如,由托管代码之外的其他程序或代码分配的内存。因此GC无法自动管理。