DataSet与DataTable重复代码能否实现DRY优化?泛型尝试已失败
消除重复代码的解决方案
当然可以消除这两段重复代码,核心思路是将公共的SqlDataAdapter初始化和数据填充逻辑提取出来,仅把创建DataSet/DataTable的差异部分单独处理。以下是几种实用方案:
方案一:提取公共逻辑+类型判断
先封装通用的数据填充逻辑,通过类型判断调用对应的Fill重载:
private static void FillWithAdapter(SqlCommand command, object dataContainer) { // 使用using确保适配器被正确释放 using var adapter = new SqlDataAdapter(command); if (dataContainer is DataSet dataSet) { adapter.Fill(dataSet); } else if (dataContainer is DataTable dataTable) { adapter.Fill(dataTable); } else { throw new ArgumentException("仅支持DataSet或DataTable类型"); } } // 对外暴露的DataSet处理方法 public static DataSet GetDataSet(SqlCommand command) { var dataSet = new DataSet(); FillWithAdapter(command, dataSet); return dataSet; } // 对外暴露的DataTable处理方法 public static DataTable GetDataTable(SqlCommand command) { var dataTable = new DataTable(); FillWithAdapter(command, dataTable); return dataTable; }
方案二:泛型+动态类型(更简洁)
利用C#的动态类型让运行时自动解析Fill重载,避免显式类型判断:
private static T FillData<T>(SqlCommand command, Func<T> createInstance) where T : class { using var adapter = new SqlDataAdapter(command); dynamic result = createInstance(); adapter.Fill(result); return result; } public static DataSet GetDataSet(SqlCommand command) { return FillData(command, () => new DataSet()); } public static DataTable GetDataTable(SqlCommand command) { return FillData(command, () => new DataTable()); }
为什么直接用泛型会失败?
你遇到的问题本质是:DataSet和DataTable没有共同的接口或基类(除了基础的Component)来让编译器确认它们能被SqlDataAdapter.Fill方法接受。编译器在编译时无法推断泛型类型是否匹配Fill的重载参数,所以直接写where T : xxx无法满足要求。上面的方案通过运行时类型检查或动态类型解析,绕开了编译时的限制,同时保留了类型安全。
内容的提问来源于stack exchange,提问作者J. Mini
相关产品推荐
相关产品推荐

