【发布时间】:2017-06-12 07:51:47
【问题描述】:
在以下代码中:
public sealed class Switch
{
public static MyObj s_object = new MyObj();
private readonly SomeObject m_object = new SomeObject();
~Switch()
{
m_object?.Dispose();
}
}
public class Test()
{
Test()
{
Switch switch = new Switch();
switch = null;
...
}
}
当 Test ctor 执行时,会创建一个新的 Switch 对象,然后立即将其设置为 null。在某些时候,GC 会处理它,在此过程中调用 ~Switch() 析构函数。但是当一个类包含像s_object 这样的静态字段并且调用应用程序没有终止(应用程序域仍然加载)时,会发生这种情况吗?静态对象在应用程序的生命周期内持续存在;这是否意味着包含它的非静态类也会?
【问题讨论】:
-
我不知道这是否适用于你的情况,但一般你应该自己实现
IDisposable来清理资源,并且只有在有非托管的东西需要清理时才使用析构函数。跨度> -
@C.Evenhuis C# 甚至没有析构函数,它有完成不同工作的终结器
-
@C.Evenhuis 考虑到我们可以看到终结器的定义,我们实际上可以看到没有非托管资源,因此应该没有终结器,而是应该实现
IDisposalbe。 -
@DiskCrasher 我希望它确实如此(如果可能通过一些间接层),但如果感觉它是,它负责在终结器中清理它们值得。
MyObj本身是一个托管对象(即使它包含非托管资源),因此,您根本不应该在终结器中访问它。 -
@DiskCrasher 如果它是一个类,它就是一个托管对象。非托管对象类似于文件句柄、网络套接字等。
Socket类是一个 托管 对象,负责管理 非托管 资源(实际操作系统插座)。处理一个类总是 100% 的时间,一个托管操作,你不应该在终结器中这样做。比如说,一个非托管资源会调用一个 OS 钩子来告诉它你不再需要一个套接字并且它应该被关闭(这就是Socket类在 its 中所做的事情终结器)。