You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 02:17:16