如何在C#中用条件列表与循环替代冗长重复的if-else语句?
如何用C#的条件列表+循环优化冗长的if-else代码块
当业务场景中存在大量不同条件,且执行逻辑高度重复、仅少数变量值有差异时,很容易写出冗余的if-else代码块,示例如下:
if (condition1 == 0 || condition2 == 0) { variable1 = 1; variable2 = 100; Reason = "Status is this"; } else if (condition3 == 1 || condition4 == 100) { variable1 = 1; variable2 = 100; Reason = "Status is something else"; } else if (condition5 == 2 || condition6 == 10) { variable1 = 1; variable2 = 100; Reason = "Status is more"; }
这类代码的问题很明显:新增条件只能不断追加else-if块,维护成本高,可读性差。你提出的列表循环方案已经是很好的优化方向:
var ConditionsList = new List<(bool Condition, string Reason)> { (condition1 == 0 || condition2 == 0, "Status is this"), (condition3 == 1 || condition4 == 100, "Status is something else"), (condition5 == 2 || condition6 == 10, "Status is more") }; foreach (var condition in ConditionsList) { if(condition.Condition) { variable1 = 1; variable2 = 100; Reason = condition.Reason; break; // 匹配到第一个符合条件的规则后终止循环 } }
该方案通过将条件与结果参数封装为元组列表,实现了新增条件仅需添加一行的目标,代码紧凑易读。针对不同场景,还有以下几种更优的进阶方案:
1. 封装规则类(灵活适配参数变化)
如果后续可能出现不同条件对应不同variable1/variable2值的情况,可以用记录类封装完整的规则逻辑,结合Linq简化匹配过程:
// 定义规则记录,包含条件判断逻辑和要设置的参数 public record ConditionRule(Func<bool> CheckCondition, int TargetVar1, int TargetVar2, string StatusReason); // 初始化规则列表 var statusRules = new List<ConditionRule> { new(() => condition1 == 0 || condition2 == 0, 1, 100, "Status is this"), new(() => condition3 == 1 || condition4 == 100, 1, 100, "Status is something else"), new(() => condition5 == 2 || condition6 == 10, 2, 200, "Status is more") // 示例:某个规则的参数不同 }; // 匹配第一个符合条件的规则 var matchedRule = statusRules.FirstOrDefault(rule => rule.CheckCondition()); if (matchedRule != null) { variable1 = matchedRule.TargetVar1; variable2 = matchedRule.TargetVar2; Reason = matchedRule.StatusReason; }
这种方式把条件判断和参数完全解耦,后续修改或新增规则时无需调整循环逻辑,灵活性更强。
2. 字典映射(适用于离散键值匹配场景)
如果条件可以转化为单一的离散值(比如状态码、枚举值),用字典映射的方式效率更高(查找复杂度O(1)),代码也更简洁:
// 假设我们可以将条件转化为一个统一的键(比如statusCode) var statusMapping = new Dictionary<int, (int Var1, int Var2, string Reason)> { [0] = (1, 100, "Status is this"), [1] = (1, 100, "Status is something else"), [2] = (1, 100, "Status is more") }; // 匹配键值并赋值 if (statusMapping.TryGetValue(GetCurrentStatusCode(), out var result)) { variable1 = result.Var1; variable2 = result.Var2; Reason = result.Reason; }
注意:该方案仅适用于条件可转化为单一键的场景,无法处理复杂的多条件判断。
3. 策略模式(适用于复杂业务逻辑扩展)
如果每个条件对应的执行逻辑差异较大,且后续有大量扩展需求,策略模式是更符合开闭原则的选择:
// 定义策略接口 public interface IStatusHandler { bool IsMatch(); void Execute(ref int var1, ref int var2, ref string reason); } // 实现具体策略类 public class ZeroStatusHandler : IStatusHandler { private readonly int _cond1; private readonly int _cond2; public ZeroStatusHandler(int cond1, int cond2) { _cond1 = cond1; _cond2 = cond2; } public bool IsMatch() => _cond1 == 0 || _cond2 == 0; public void Execute(ref int var1, ref int var2, ref string reason) { var1 = 1; var2 = 100; reason = "Status is this"; } } // 其他策略类类似实现... // 使用策略列表匹配执行 var handlers = new List<IStatusHandler> { new ZeroStatusHandler(condition1, condition2), new OneStatusHandler(condition3, condition4), new TwoStatusHandler(condition5, condition6) }; var matchedHandler = handlers.FirstOrDefault(h => h.IsMatch()); matchedHandler?.Execute(ref variable1, ref variable2, ref Reason);
这种方式将每个条件的判断与执行逻辑完全封装在独立类中,新增条件只需新增策略类,无需修改原有代码,适合复杂业务场景的长期维护。
总结
你提出的列表循环方案已经能解决大部分简单场景的冗余if-else问题,进阶方案的选择取决于业务需求:
- 简单参数赋值场景:你的原方案或规则类方案足够简洁;
- 离散键值匹配场景:字典映射效率更高;
- 复杂逻辑扩展场景:策略模式更符合软件工程原则。
内容的提问来源于stack exchange,提问作者Harold
相关产品推荐
相关产品推荐

