You need to enable JavaScript to run this app. C# 如何将两个ConvertToDictionary重载方法合并为单个泛型方法
优惠活动
大模型
产品
解决方案
定价
更多

C# 如何将两个ConvertToDictionary重载方法合并为单个泛型方法

消除重复重载:ConvertToDictionary 泛型合并方案

当前两个ConvertToDictionary方法的执行逻辑100%重合,仅入参类型存在差异,完全可以通过泛型消除重复代码,不需要保留两个重载版本。

核心共性分析

对比现有类结构,可以提炼出两个场景的完全一致的执行逻辑依赖项:

  • 两类字典类(DgDictHosp/DgDictOper)都具备long类型的Key属性,是最终生成字典的键
  • 字典类的Data属性存放的实体(Hospitalization/Operation)都包含IDDiagnosis属性,是调用ToLiteral方法的唯一入参

基于这两个共性,就可以设计通用的泛型逻辑,不需要为每个类型单独写方法。


方案1:零侵入泛型适配(推荐优先选用,完美适配EF生成实体场景)

如果你的Hospitalization/Operation是EF自动生成的实体,不要直接修改实体文件的代码——后续在可视化设计器中调整模型、重新生成代码时,手动改动的内容会被直接覆盖。这种场景下完全可以通过泛型+委托传参的方式实现通用方法,不需要依赖任何公共基类或接口:

public static Dictionary<long, DictItem> ConvertToDictionary<TCollection, TEntity>(
    List<TCollection> list_g,
    Func<TCollection, IEnumerable<TEntity>> getDataSource,
    Func<TEntity, int> getDiagnosisId)
{
    return list_g.Select(q => new DictItem
    {
        Id = q.Key,
        List = getDataSource(q)
            .Select(t => ToLiteral(getDiagnosisId(t)))
            .ToList()
    }).ToDictionary(k => k.Id);
}

原有业务逻辑的调用方式只需要做极小调整,不需要改动上层分组逻辑:

  1. 原GetHospDict方法内的调用替换为:
    var res = ConvertToDictionary(
        res_g,
        dictItem => dictItem.Data,
        entity => entity.IDDiagnosis);
    
  2. 原GetOperDict方法内的调用替换为:
    var res = ConvertToDictionary(
        res_g,
        dictItem => dictItem.Data,
        entity => entity.IDDiagnosis);
    

注意:调用时编译器会自动根据入参类型推断泛型参数,不需要手动指定泛型类型,和原有重载方法的调用体验完全一致。


方案2:强类型约束实现(适合可修改公共抽象层的长期维护场景)

如果项目中可以配套给EF实体定义抽象接口(不直接修改EF生成的类文件,而是通过partial类扩展实现接口),可以把方法的泛型约束收紧,进一步简化调用逻辑,不需要每次传委托参数:

  1. 先定义共性接口:
    // 所有带诊断ID的实体都实现该接口
    public interface IHasDiagnosis
    {
        int IDDiagnosis { get; }
    }
    
    // 所有字典类的公共抽象
    public interface IDgDict<TEntity> where TEntity : IHasDiagnosis
    {
        long Key { get; }
        IEnumerable<TEntity> Data { get; }
    }
    
  2. 通过EF的partial类机制让实体实现接口,不会被模型重新生成覆盖:
    public partial class Hospitalization : IHasDiagnosis {}
    public partial class Operation : IHasDiagnosis {}
    public partial class DgDictHosp : IDgDict<Hospitalization> {}
    public partial class DgDictOper : IDgDict<Operation> {}
    
  3. 简化后的通用泛型方法:
    public static Dictionary<long, DictItem> ConvertToDictionary<TEntity>(
        List<IDgDict<TEntity>> list_g) where TEntity : IHasDiagnosis
    {
        return list_g.Select(q => new DictItem
        {
            Id = q.Key,
            List = q.Data.Select(t => ToLiteral(t.IDDiagnosis)).ToList()
        }).ToDictionary(k => k.Id);
    }
    
    这种场景下调用方法时完全不需要传额外的委托参数,和原有重载方法的调用方式没有任何区别,后续如果新增其他类型的字典(比如门诊记录、急诊记录),只要实现对应接口就能直接复用方法。

额外优化点

观察现有类结构可以发现:DgDictHosp和DgDictOper里的List属性在ConvertToDictionary的执行逻辑中从未被读取或使用,属于冗余字段,完全可以从类定义中删除,减少不必要的内存占用。

内容的提问来源于stack exchange,提问作者petr.f77

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.07 00:45:07