我知道当实例化该类的新实例时,类的实例变量会生效,并且当没有对该实例的引用时,实例的析构函数已执行。但是结构中的实例变量生命周期呢?
感谢。
答案 0 :(得分:3)
当没有对该实例的引用时,实例的析构函数已执行
只有如果该类具有析构函数(否则,其内存只是回收),如果 GC.SuppressFinalize
尚未在该对象上调用,并且当垃圾收集器决定收集该对象所属的生成时。
另请注意,销毁对象与回收其内存不同。 当GC调用对象的析构函数时,该对象将被提升到下一代,并且只有在GC决定收集 生成时才会回收其内存,如果仍然存在没有强烈的引用。
这就是为什么通过创建对自身的强引用(例如,将自己分配给静态字段)来复活一个对象是可能的(但不要这样做!)在析构函数中。
但结构中的实例变量生命周期怎么样?
如果它们是在一个方法中声明而不是泄露在任何地方(例如在闭包中使用它,或被分配给一个字段成员),很可能它们会被放在堆栈中并且在方法结束时确定性地删除,并且GC将永远不会知道它。
如果他们被分配到一个领域,只要封闭的阶级生活,他们就会活着。
此外,结构不能有析构函数。
答案 1 :(得分:2)
首先,事实并非如此,如果没有对实例的引用,则会调用它的析构函数。真正发生的事情是,在垃圾收集器的选择时,对象被标记为垃圾,然后再次在垃圾收集器的选择时,对象被销毁。
对于结构,您必须记住,该结构的行为与任何其他值类型对象(如int,float等)的行为类似。因此,例如,如果将结构保留在局部变量中并退出方法,则从堆栈中删除结构,从而清除对其所有字段的所有引用 - 如果它们是引用类型(并且不存在其他引用),则它们GC将按照我之前描述的相同方式收集。如果它们是值类型的,则会立即删除它们。
上详细了解此事答案 2 :(得分:1)
您应该阅读Garbage Collection,因为您做出的假设是完全错误的。当没有任何东西引用某个对象时,GC 可以收集它,但你不会准确知道何时。此外,C#没有析构函数,它具有finalizers,与析构函数相比,它们不具有确定性。语法与C ++析构函数相同,但它们之间的区别是不同的。
引用类型(类)和值类型(结构)之间的区别在于,如果没有对它们的有效引用,则引用类型将被垃圾收集,其中值类型在超出范围时被收集。像int
,IntPtr
等类型都是结构并遵循相同的规则。
答案 3 :(得分:0)
根据MSDN:
“结构的实例变量与它所属的结构变量具有完全相同的生命周期,即,当结构类型的变量存在或不再存在时,结构的实例变量也是如此。 “
来源:http://msdn.microsoft.com/en-us/library/aa691165(v=vs.71).aspx
(虽然它实际上被垃圾收集器破坏了。)