C# 类与结构中的实例变量生存期

C# 类与结构中的实例变量生存期,c#,.net,C#,.net,我知道,当一个类的新实例被实例化时,一个类的实例变量开始生效,并且当没有对该实例的引用时,该实例的析构函数已经执行。但是结构中的实例变量生命周期呢 谢谢。首先,如果没有对实例的引用,则调用实例的析构函数是不对的。真正发生的情况是,在垃圾收集器选择时,对象被标记为垃圾,然后,在垃圾收集器选择时,对象再次被销毁 对于结构,您必须记住,该结构的行为类似于任何其他值类型对象(如int、float等)。因此,例如,如果您将结构保留在局部变量中并退出该方法,则结构将从堆栈中删除,从而清除对其所有字段的所有引

我知道,当一个类的新实例被实例化时,一个类的实例变量开始生效,并且当没有对该实例的引用时,该实例的析构函数已经执行。但是结构中的实例变量生命周期呢


谢谢。

首先,如果没有对实例的引用,则调用实例的析构函数是不对的。真正发生的情况是,在垃圾收集器选择时,对象被标记为垃圾,然后,在垃圾收集器选择时,对象再次被销毁

对于结构,您必须记住,该结构的行为类似于任何其他值类型对象(如int、float等)。因此,例如,如果您将结构保留在局部变量中并退出该方法,则结构将从堆栈中删除,从而清除对其所有字段的所有引用—如果它们是引用类型的(并且不存在其他引用),则GC将以我前面描述的相同方式收集它们。如果它们是值类型的,则会立即删除

您可以根据MSDN在和上阅读有关此问题的更多信息:

结构的实例变量与其所属的结构变量具有完全相同的生存期,即当结构类型的变量开始存在或停止存在时,结构的实例变量也是如此

资料来源:

(虽然它实际上是被垃圾收集器破坏的)

当没有对该实例的引用时,该实例的析构函数已执行

仅当该类具有析构函数(否则,它的内存被简单地回收)、未对该对象调用
GC.SuppressFinalize
以及垃圾收集器决定收集该对象所属的生成时

还要注意,销毁对象与回收其内存是不同的。 当GC调用一个对象的析构函数时,该对象将被提升到下一代,并且只有在GC下次决定收集该代时(如果仍然没有对它的强引用),才会回收其内存

这就是为什么通过在析构函数中创建对自身的强引用(例如,将自身指定给静态字段),可以(但不要这么做!)复活对象

但是结构中的实例变量生命周期呢

如果它们是在方法中声明的,并且没有泄漏到任何地方(例如在闭包中使用它,或者被分配给字段成员),那么它们很可能会被放在堆栈上,并在方法结束时被决定性地删除,GC永远不会知道这一点

如果它们被分配到一个字段,它们将与封闭类的寿命一样长


此外,结构不能有析构函数。

您可能应该仔细阅读,因为您所做的假设是完全错误的。当没有任何东西引用一个对象时,GC可能会收集它,但您不知道确切的时间。而且,C#没有析构函数,它有,这与析构函数不同,是不确定的。语法与C++析构函数相同,但在引擎盖下它们是不同的。
引用类型(类)和值类型(结构)之间的区别在于,如果不再存在对引用类型的有效引用,则会对引用类型进行垃圾收集,而值类型在超出范围时会被收集。像
int
IntPtr
等类型都是结构,遵循相同的规则。

只是提醒一下,它们在C#中被称为终结器,而不是析构函数。@GazTheDestroyer C#规范将它们称为析构函数(第§1.6.7.6节)。@GazTheDestroyer令人困惑的是,它们实际上被称为析构函数(即使它们在技术上是终结器)。好吧,现在我很困惑!:)您还可以添加和当垃圾收集器没有明确要求为了完整性而禁止此终结器时。