C# WinForm多窗体重复代码优化:通用基类实现方法
WinForm 图书管理系统窗体冗余代码重构方案
你现在遇到的重复代码本质是所有业务窗体都遵循「DAL层实例初始化→异步拉取数据→切回UI线程→绑定控件数据→渲染UI文本」的固定执行流程,差异仅在各窗体自己的DAL类型、数据查询规则、控件绑定逻辑、UI文本配置这几个部分。基类只需要把固定流程全部封装,把差异点开放为可重写的虚方法交给子类实现即可,完全可以消除你贴出来的这类重复代码。
基类需要封装的通用逻辑
- 统一绑定窗体Load事件,不需要每个业务窗体手动绑定事件处理方法
- 统一做DAL实例的空值判断与初始化,不需要每个窗体重复写判空new实例的代码
- 统一封装异步任务执行完成后的跨线程回调逻辑,把重复的
InvokeRequired判断全部收敛到基类 - 统一加异步执行的异常兜底,避免数据加载失败时程序直接崩溃,不需要每个窗体单独写异常处理
基类具体实现
推荐用泛型基类,自动适配每个窗体对应的DAL类型,代码如下:
// 泛型参数TDAL为各窗体对应的DAL类型,约束为必须带无参构造函数,方便基类自动初始化 public class BaseBusinessForm<TDAL> : Form where TDAL : class, new() { // 子类可以直接访问基类初始化好的DAL实例 protected TDAL _dal; public BaseBusinessForm() { // 基类统一订阅Load事件,子类无需重复绑定 this.Load += BaseBusinessForm_Load; } private void BaseBusinessForm_Load(object sender, EventArgs e) { // 统一初始化DAL实例 _dal ??= new TDAL(); // 统一执行异步数据加载流程 loadData().ContinueWith(t => { // 统一封装UI线程回调逻辑 Action uiInvokeAction = () => { // 统一处理加载异常 if (t.IsFaulted) { MessageBox.Show($"数据加载失败:{t.Exception?.InnerException?.Message}"); return; } bindingData(); applyUIStrings(); }; if (InvokeRequired) { Invoke(uiInvokeAction); } else { uiInvokeAction(); } }, TaskScheduler.Default); } /// <summary> /// 可重写方法:子类实现自身的数据查询逻辑,基类默认空实现 /// </summary> protected virtual Task loadData() { return Task.CompletedTask; } /// <summary> /// 可重写方法:子类实现自身的控件数据绑定逻辑 /// </summary> protected virtual void bindingData() { } /// <summary> /// 可重写方法:子类实现自身的UI文本设置(含多语言)逻辑 /// </summary> protected virtual void applyUIStrings() { } }
子类改造方式
改造后业务窗体只需要保留自身的差异逻辑,所有重复流程代码全部删除。以你贴的两个窗体为例:
AuthorForm改造后代码
// 继承基类时指定当前窗体对应的DAL类型为AuthorDAL public partial class AuthorForm : BaseBusinessForm<AuthorDAL> { public AuthorForm() { InitializeComponent(); } // 仅重写三个差异方法即可 protected override async Task loadData() { // 这里写作者数据查询逻辑,直接用基类初始化好的_dal即可 // 示例:var authorList = await _dal.GetListAsync(); 结果存为窗体级变量供绑定时使用 } protected override void bindingData() { // 这里写作者数据和文本框、DataGridView等控件的绑定逻辑 } protected override void applyUIStrings() { // 这里写窗体标题、按钮文本、多语言配置等逻辑 Text = "作者管理"; } }
BookTypeForm改造后代码
// 继承基类时指定当前窗体对应的DAL类型为BookTypeDAL public partial class BookTypeForm : BaseBusinessForm<BookTypeDAL> { public BookTypeForm() { InitializeComponent(); } protected override async Task loadData() { // 写图书分类数据查询逻辑 } protected override void bindingData() { // 写图书分类数据的控件绑定逻辑 } protected override void applyUIStrings() { Text = "图书分类管理"; } }
后续可扩展抽到基类的通用逻辑
等这套基类跑通后,你还可以逐步把其他重复逻辑收敛到基类,进一步减少冗余:
- 新增、编辑、删除按钮的通用权限校验
- 分页控件的通用绑定、页码切换逻辑
- 数据修改后刷新列表的通用触发逻辑
- 窗体关闭时的异步任务取消、资源释放逻辑,避免窗体释放后后台任务回调抛跨线程异常
内容的提问来源于stack exchange,提问作者QuangGiap
相关产品推荐
相关产品推荐

