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

C# .NET 6医疗评分计算:如何避免Switch语句?规则引擎替代方案

解决方案:结构化实现医疗评分计算

针对你的需求,规则设计模式完全不算过度设计——15个变量的医疗评分逻辑如果用硬编码的switch/if堆叠,会导致代码臃肿、难以维护,且医疗规则可能随指南更新而调整,结构化的实现方式能大幅提升可维护性、可测试性和扩展性。

下面提供两种适合.NET 6场景的落地方案:

方案一:策略模式+规则类封装

把每个变量的评分逻辑封装成独立的规则类,通过统一接口聚合计算,符合开闭原则,每个规则可单独测试和修改。

1. 定义规则接口

public interface IScoringRule
{
    // 接收患者数据,返回该规则对应的分数
    int CalculateScore(PatientData patientData);
}

2. 实现单个变量的规则类

以射血分数为例,用C# 8的模式匹配简化判断:

public class EjectionFractionRule : IScoringRule
{
    public int CalculateScore(PatientData patientData)
    {
        return patientData.EjectionFraction switch
        {
            < 20 => 7,
            >= 20 and <= 24 => 6,
            >= 25 and <= 29 => 5,
            >= 30 and <= 34 => 3,
            >= 35 and <= 39 => 2,
            >= 40 => 0,
            _ => 0
        };
    }
}

你可以为年龄、肌酐等其他14个变量分别创建对应的AgeRule、CreatinineRule等类。

3. 实现评分计算器

通过依赖注入聚合所有规则,统一计算总分:

public class ScoringCalculator
{
    private readonly IEnumerable<IScoringRule> _allRules;

    // 构造函数注入所有规则
    public ScoringCalculator(IEnumerable<IScoringRule> allRules)
    {
        _allRules = allRules;
    }

    public int CalculateTotalScore(PatientData patientData)
    {
        // 遍历所有规则,累加分数
        return _allRules.Sum(rule => rule.CalculateScore(patientData));
    }
}

4. 注册依赖(Program.cs)

// 注册所有规则类
builder.Services.AddScoped<IScoringRule, EjectionFractionRule>();
builder.Services.AddScoped<IScoringRule, AgeRule>();
// ... 注册剩余13个规则类
builder.Services.AddScoped<ScoringCalculator>();

方案二:配置驱动的规则计算

如果规则需要频繁调整(比如医疗指南更新),可以把区间和分数定义在配置文件中,无需修改代码即可更新规则。

1. 配置文件(appsettings.json)

"ScoringRules": {
  "EjectionFraction": [
    {"Min": null, "Max": 19, "Score": 7},
    {"Min": 20, "Max": 24, "Score": 6},
    {"Min": 25, "Max": 29, "Score": 5},
    {"Min": 30, "Max": 34, "Score": 3},
    {"Min": 35, "Max": 39, "Score": 2},
    {"Min": 40, "Max": null, "Score": 0}
  ],
  "Age": [
    {"Min": null, "Max": 64, "Score": 0},
    {"Min": 65, "Max": 74, "Score": 2},
    {"Min": 75, "Max": null, "Score": 3}
    // 其他变量规则依次添加
  ]
}

2. 配置模型类

public class ScoringConfig
{
    public Dictionary<string, List<RangeRule>> ScoringRules { get; set; }
}

public class RangeRule
{
    public int? Min { get; set; }
    public int? Max { get; set; }
    public int Score { get; set; }
}

3. 配置驱动的计算器

public class ConfigBasedScoringCalculator
{
    private readonly ScoringConfig _config;

    public ConfigBasedScoringCalculator(IConfiguration config)
    {
        _config = config.GetSection("ScoringRules").Get<ScoringConfig>();
    }

    public int CalculateTotalScore(PatientData patientData)
    {
        int total = 0;
        
        // 计算射血分数
        total += GetVariableScore(patientData.EjectionFraction, "EjectionFraction");
        // 计算年龄
        total += GetVariableScore(patientData.Age, "Age");
        // ... 处理其他13个变量
        
        return total;
    }

    private int GetVariableScore(int value, string ruleKey)
    {
        if (!_config.ScoringRules.TryGetValue(ruleKey, out var rules))
            return 0;
        
        foreach (var rule in rules)
        {
            bool isInRange = true;
            if (rule.Min.HasValue && value < rule.Min.Value) isInRange = false;
            if (rule.Max.HasValue && value > rule.Max.Value) isInRange = false;
            
            if (isInRange) return rule.Score;
        }
        
        return 0;
    }
}

关于规则模式的必要性

15个变量的硬编码逻辑会导致:

  • 代码冗长,单个方法可能数百行,难以定位问题
  • 修改规则时容易误改其他逻辑,风险高
  • 无法单独测试某个变量的评分逻辑

而规则模式(或上述两种变体)将每个变量的逻辑解耦,每个规则类/配置项独立,既便于测试,也能快速响应规则变更,完全符合医疗场景对准确性和可维护性的要求,绝非过度设计。

内容的提问来源于stack exchange,提问作者nitse

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 11:40:25