C# WinForm如何根据CheckedListBox选中项匹配类名获取QUERY常量
实现方案
该需求完全可以实现,核心通过C#反射机制动态匹配类、读取私有常量即可,无需硬编码多分支判断。
前置准备
- 先修正你贴出的Form1代码的语法错误:类定义末尾多了一个多余的闭合大括号,删除后保证项目可正常编译。
- 在Form1代码文件顶部引入反射所需命名空间:
using System.Reflection;
核心实现逻辑
每个SQL查询类的QUERY是私有静态常量,反射获取时需要指定匹配非公开、静态成员的绑定标志,根据选中项的名称拼接完整类型名(格式为命名空间.类名,即MyApp.SQLQueries.{选中项名}),从程序集加载对应类型后读取常量值即可。
修改后的按钮点击事件代码如下:
private void button1_Click(object sender, EventArgs e) { // 加载当前程序集,同项目下SQLQueries类默认包含在该程序集中 Assembly currentAssembly = Assembly.GetExecutingAssembly(); const string sqlClassNamespace = "MyApp.SQLQueries"; using (SqlConnection sqlCon = new SqlConnection(dbCnxStr)) { sqlCon.Open(); foreach (var item in checkedListBox1.CheckedItems) { string className = item.ToString(); // 拼接类的完整类型名 string fullTypeName = $"{sqlClassNamespace}.{className}"; // 从程序集获取对应类的类型 Type queryType = currentAssembly.GetType(fullTypeName); if (queryType == null) { MessageBox.Show($"未找到对应查询类:{className}"); continue; } // 读取类中私有静态常量QUERY的值 string sql = queryType.GetField("QUERY", BindingFlags.NonPublic | BindingFlags.Static) ?.GetValue(null) as string; if (string.IsNullOrEmpty(sql)) { MessageBox.Show($"类{className}中未找到有效QUERY常量"); continue; } DataTable dt = new DataTable(); using (SqlCommand sqlCmd = new SqlCommand(sql, sqlCon)) { using (SqlDataReader sqlRd = sqlCmd.ExecuteReader()) { if (sqlRd.HasRows) { dt.Load(sqlRd); } sqlRd.Close(); } } // 此处可自行处理查询得到的dt,比如绑定到界面控件、做数据加工等 } sqlCon.Close(); } }
补充说明
- 如果你的SQLQueries类单独放在其他类库项目,需要把
Assembly.GetExecutingAssembly()替换为对应类库的程序集加载代码,比如Assembly.Load("MyApp.SQLQueries"),注意替换成实际的程序集名称。 - 后续新增同结构的查询类时,只要保证类名和CheckedListBox新增的选项文本完全一致,不需要修改按钮点击的业务逻辑即可自动适配。
- 如果不想通过反射读取私有成员,也可以把每个类里的
QUERY常量访问修饰符改成public,反射时把BindingFlags里的NonPublic替换为Public即可。
内容的提问来源于stack exchange,提问作者kami
相关产品推荐
相关产品推荐

