Visual Studio 2022中WinForms自定义控件列表残留是否为严重Bug?
自定义控件列表残留前次运行数据的问题分析
我开发了一款包含自定义控件的应用程序,该控件的OnLoad()事件处理程序会向自身的Objects列表添加项。但停止调试并重启后,列表仍保留前一次运行时的项。调试时在Objects.Add()行设置断点,监视发现Objects列表已有前几次调试会话的多个对象,每次执行列表都会变大。后续遍历该列表的代码也会处理这些残留对象,这是否属于严重基础Bug?使用版本:Visual Studio Community 2022 17.8.5
代码示例
Public Class Display Inherits System.Windows.Forms.UserControl Public Objects As New List(Of Object) Protected Overrides Sub OnLoad(e As EventArgs) MyBase.OnLoad(e) Objects.Add(New Rectangle(0, 0, 10, 10)) End Sub End Class
问题原因与结论
这不是Visual Studio的严重基础Bug,而是对WinForms控件序列化机制不熟悉导致的设计错误:
- WinForms设计器会将自定义控件的实例状态(包括公共字段)序列化到窗体的
.Designer.vb文件中。停止调试重启后,设计器会反序列化之前保存的控件实例,Objects列表里的旧数据也就被保留下来了。 - 每次调试时
OnLoad事件又会新增项,叠加旧数据后列表自然越来越大。
解决方案
针对不同场景,有几种修正方式:
- 阻止字段序列化:如果
Objects是运行时临时数据,不需要被设计器保存,给字段加上<NonSerialized>特性:
<NonSerialized()> Public Objects As New List(Of Object)
- 构造函数初始化:在控件构造函数里初始化列表,确保每次实例化都是全新的空列表:
Public Objects As List(Of Object) Public Sub New() InitializeComponent() Objects = New List(Of Object) End Sub
- 临时修复:在
OnLoad事件中先清空列表再添加项,但这只是治标不治本的方法:
Protected Overrides Sub OnLoad(e As EventArgs) MyBase.OnLoad(e) Objects.Clear() ' 先清空旧数据 Objects.Add(New Rectangle(0, 0, 10, 10)) End Sub
内容的提问来源于stack exchange,提问作者J Collins
相关产品推荐
相关产品推荐

