You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Destructor未在程序输出中显示?请求技术协助

VB.NET中Finalize方法(析构函数)未执行的问题解决

你编写的代码里重写了Finalize方法,但运行后看不到"byebye"输出,核心原因和解决办法如下:

问题根源

.NET的垃圾回收(GC)是非确定性的:对象不再被引用后,GC不会立即执行其Finalize方法,程序结束时甚至可能跳过这一步,导致你的输出无法显示。

解决办法

方法1:手动触发垃圾回收(仅用于测试)

在Main方法末尾添加强制GC回收并等待Finalize执行的代码:

Sub main()
    Dim obj1 As suman = New suman()
    Dim obj2 As suman = New suman(10, 20)
    Dim obj3 As suman = New suman(obj2)

    ' 强制GC回收并等待Finalize完成
    GC.Collect()
    GC.WaitForPendingFinalizers()
End Sub

运行后就能看到"byebye"输出,不过这种方式只适合测试,生产环境不建议依赖手动GC。

方法2:实现IDisposable接口(推荐方案)

Finalize性能差且执行时机不可控,更可靠的方式是实现IDisposable接口,显式控制资源释放:

Imports System
Module module1
    Class suman
        Implements IDisposable
        Private c As Integer
        Private disposedValue As Boolean = False ' 防止重复释放

        Sub New()
            Console.WriteLine("Default constructor")
        End Sub

        Sub New(ByVal x As Integer, ByVal y As Integer)
            c = x + y
            Console.WriteLine(c)
        End Sub
        Sub New(ByVal obb As suman)
            c = obb.c
            Console.WriteLine(obb.c)
        End Sub

        ' 核心释放逻辑
        Protected Overridable Sub Dispose(disposing As Boolean)
            If Not disposedValue Then
                If disposing Then
                    ' 这里释放托管资源(如其他IDisposable对象)
                End If
                ' 这里释放非托管资源,同时输出日志
                Console.WriteLine("byebye")
                disposedValue = True
            End If
        End Sub

        ' 对外暴露的Dispose方法
        Public Sub Dispose() Implements IDisposable.Dispose
            Dispose(True)
            GC.SuppressFinalize(Me) ' 告诉GC无需再执行Finalize
        End Sub

        ' Finalize作为兜底,防止未调用Dispose时泄露资源
        Protected Overrides Sub Finalize()
            Dispose(False)
            MyBase.Finalize()
        End Sub
    End Class

    Sub main()
        ' Using语句会自动调用obj1的Dispose
        Using obj1 As suman = New suman()
            Dim obj2 As suman = New suman(10, 20)
            Dim obj3 As suman = New suman(obj2)
            
            ' 显式调用Dispose释放obj2和obj3
            obj2.Dispose()
            obj3.Dispose()
        End Using
    End Sub
End Module

这种方式能确保资源被及时释放,Using语句还能自动处理IDisposable对象的生命周期,避免遗漏。

注意事项

Finalize方法仅用于清理非托管资源,不要用它做业务输出或依赖它执行关键逻辑——因为你永远无法确定它什么时候会运行。

内容的提问来源于stack exchange,提问作者Suman Devkota

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 20:06:22