如何无需if else动态调用泛型方法,匹配对应集合生成DataTable
实现方案
你完全可以借助已加的[Description]特性去掉所有if else分支,也可以选择手动构建映射字典的轻量方案,两种实现如下:
注意:原代码存在两个可修复的问题:
- 你定义的A、B、C类中的A1/A2等是公共字段而非属性,原
CreateTable中用GetProperties()无法获取到对应值,需要改为GetFields()- 原
CreateTable方法生成行数据后没有将行添加到DataTable的Rows集合中,返回的表格会为空
方案1:借助[Description]特性实现(零硬编码,易扩展)
核心思路是启动时反射扫描DataSource的所有字段,提取Description标记和对应集合的映射关系,后续直接查表即可,新增类无需修改业务逻辑:
using System.ComponentModel; using System.Reflection; using System.Data; using System.Collections; public DataSet CreateTablesFromString(char[] lstchar) { DataSource ds = new DataSource(); DataSet dataset = new DataSet(); // 构建字符到集合的映射字典,可全局缓存复用无需重复生成 var dsType = typeof(DataSource); var charMap = dsType.GetFields() .Where(f => Attribute.IsDefined(f, typeof(DescriptionAttribute))) .ToDictionary( f => ((DescriptionAttribute)f.GetCustomAttribute(typeof(DescriptionAttribute))).Description[0], f => (IEnumerable)f.GetValue(ds) ); foreach (var c in lstchar) { if (charMap.TryGetValue(c, out var dataList)) { dataset.Tables.Add(CreateTable(dataList.Cast<object>().ToList())); } } return dataset; } // 修复后的通用表格生成方法 private DataTable CreateTable(List<object> lstData) { if (lstData == null || lstData.Count == 0) return new DataTable(); var elementType = lstData[0].GetType(); var fields = elementType.GetFields(); DataTable dt = new DataTable(elementType.Name); // 初始化列 foreach (var field in fields) { dt.Columns.Add(field.Name, field.FieldType); } // 填充行数据 foreach (var item in lstData) { var row = dt.NewRow(); foreach (var field in fields) { row[field.Name] = field.GetValue(item) ?? DBNull.Value; } dt.Rows.Add(row); } return dt; }
后续如果新增D类,只需要给DataSource加[Description("D")] public List<D> LstD;即可,不需要修改任何业务逻辑。
方案2:手动构建映射字典(性能更高,无需反射)
如果不想引入反射开销,也可以手动写映射字典,比if else易维护很多:
public DataSet CreateTablesFromString(char[] lstchar) { DataSource ds = new DataSource(); DataSet dataset = new DataSet(); // 新增类型只需要加一行映射即可 var charMap = new Dictionary<char, IEnumerable> { {'A', ds.LstA}, {'B', ds.LstB}, {'C', ds.LstC} }; foreach (var c in lstchar) { if (charMap.TryGetValue(c, out var dataList)) { dataset.Tables.Add(CreateTable(dataList.Cast<object>().ToList())); } } return dataset; }
CreateTable方法同方案1。
内容的提问来源于stack exchange,提问作者edjoker
相关产品推荐
相关产品推荐

