当 class 包含静态字段时,是否会调用 C# class 析构函数?
Will a C# class destructor be called when the class contains static fields?
在下面的代码中:
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;
...
}
}
当测试构造函数执行时,会创建一个新的 Switch 对象,然后立即将其设置为 null。在某些时候,GC 将处理它,并在此过程中调用 ~Switch()
析构函数。但是当 class 包含一个像 s_object
这样的静态字段并且调用应用程序没有终止(应用程序域仍然加载)时会发生这种情况吗?静态对象在应用程序的生命周期内持续存在;这是否意味着包含它的非静态 class 也会如此?
这应该不是问题。就内存表示而言,静态字段与定义类型的实例不相关。
查看此 post 了解更多详细信息:How exactly do static fields work internally?
静态字段的存在对对象将被垃圾收集(并因此最终确定)的时间没有影响。该实例将在与没有静态字段的情况下发生的时间相当的时刻完成。
静态字段对实例的唯一影响是静态初始化发生在第一个实例创建之前,因此可能使第一个实例的创建比其余实例慢。
注意:post 中的代码显示终结器的无效实现,因为它引用其他托管对象并尝试调用其上的方法。这两种情况都会导致未定义的行为(with/without 静态字段)。
在下面的代码中:
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;
...
}
}
当测试构造函数执行时,会创建一个新的 Switch 对象,然后立即将其设置为 null。在某些时候,GC 将处理它,并在此过程中调用 ~Switch()
析构函数。但是当 class 包含一个像 s_object
这样的静态字段并且调用应用程序没有终止(应用程序域仍然加载)时会发生这种情况吗?静态对象在应用程序的生命周期内持续存在;这是否意味着包含它的非静态 class 也会如此?
这应该不是问题。就内存表示而言,静态字段与定义类型的实例不相关。
查看此 post 了解更多详细信息:How exactly do static fields work internally?
静态字段的存在对对象将被垃圾收集(并因此最终确定)的时间没有影响。该实例将在与没有静态字段的情况下发生的时间相当的时刻完成。
静态字段对实例的唯一影响是静态初始化发生在第一个实例创建之前,因此可能使第一个实例的创建比其余实例慢。
注意:post 中的代码显示终结器的无效实现,因为它引用其他托管对象并尝试调用其上的方法。这两种情况都会导致未定义的行为(with/without 静态字段)。