C#中switch case如何使用变量?非常量场景解决方案
C#中非常量匹配场景的替代方案
针对你提到的switch无法使用非常量case,且匹配值数量较多的情况,推荐以下几种实用方案:
1. 字典映射(最适合大量匹配场景)
把匹配值和对应的处理逻辑封装成键值对,利用字典的O(1)查找效率,比链式if/else高效得多。注意float作为字典键要考虑精度问题,建议先做精度处理(比如转成double并保留指定小数位)。
示例代码:
float value = 4; float number1 = 3, number2 = 6, number3 = 4; // 处理float精度问题,转成double保留2位小数(可根据需求调整) var matchActions = new Dictionary<double, Action> { { Math.Round((double)number1, 2), () => { /* number1匹配时的逻辑 */ } }, { Math.Round((double)number2, 2), () => { /* number2匹配时的逻辑 */ } }, { Math.Round((double)number3, 2), () => { /* number3匹配时的逻辑 */ } } }; double key = Math.Round((double)value, 2); if (matchActions.TryGetValue(key, out var action)) { action.Invoke(); } else { // 无匹配时的默认逻辑 }
如果需要传递参数,可改用Dictionary<double, Action<YourParameterType>>扩展。
2. C# 8.0+ switch表达式(支持变量匹配)
C# 8.0及以上的switch表达式支持when子句实现变量匹配,写法更简洁,但匹配值过多时会显得冗长,适合中等数量的场景:
float value = 4; float number1 = 3, number2 = 6, number3 = 4; var result = value switch { var v when Math.Abs(v - number1) < 1e-6 => /* 匹配number1的逻辑/返回值 */, var v when Math.Abs(v - number2) < 1e-6 => /* 匹配number2的逻辑/返回值 */, var v when Math.Abs(v - number3) < 1e-6 => /* 匹配number3的逻辑/返回值 */, _ => /* 默认逻辑/返回值 */ };
3. 集合遍历匹配(适合动态规则场景)
把所有匹配值和处理逻辑放到集合中,遍历查找匹配项,适合需要动态添加/移除匹配规则的场景:
float value = 4; float number1 = 3, number2 = 6, number3 = 4; var matchRules = new List<(float MatchValue, Action Handler)> { (number1, () => { /* number1处理逻辑 */ }), (number2, () => { /* number2处理逻辑 */ }), (number3, () => { /* number3处理逻辑 */ }) }; var matchedRule = matchRules.FirstOrDefault(r => Math.Abs(r.MatchValue - value) < 1e-6); if (matchedRule.Handler != null) { matchedRule.Handler.Invoke(); }
关键注意事项
- 浮点精度问题:float/double直接用
==比较易出错,建议通过判断两值差的绝对值是否小于精度阈值(如1e-6)来匹配。 - 性能对比:字典映射的查找效率为O(1),适合100+的大量匹配场景;链式if/else为O(n),数量越多性能差距越明显。
内容的提问来源于stack exchange,提问作者akinnuri
相关产品推荐
相关产品推荐

