如何从char获取+-/*运算符?C#无需switch case实现动态运算
嘿,这个问题挺有意思的——你想要的其实是动态绑定运算符行为,同时避开繁琐的switch/case对吧?我分两个部分给你拆解:
解决方案:动态运算符映射 + 合法运算符筛选
一、先解决:从char中提取合法运算符(+、-、*、/)
核心思路是先定义合法运算符的集合,再做匹配或筛选,下面两种方法各有适用场景:
方法1:用HashSet做快速验证(推荐)
HashSet的查找是O(1),性能拉满,适合单个char的合法性校验,或者批量提取合法运算符:
// 定义合法运算符集合 var validOperators = new HashSet<char> { '+', '-', '*', '/' }; // 单个char验证 char h = '+'; bool isLegalOperator = validOperators.Contains(h); // 返回true // 从char数组/序列中提取所有合法运算符 char[] inputChars = { 'a', '+', '3', '-', '*', 'z' }; var extractedOperators = inputChars.Where(c => validOperators.Contains(c)).ToList(); // 结果:['+', '-', '*']
方法2:正则表达式(适合字符串场景)
如果是从长字符串里提取运算符,正则会更灵活:
string input = "g + 5 - 3 * 2"; var matches = Regex.Matches(input, @"[+\-*/]"); var operators = matches.Cast<Match>().Select(m => m.Value[0]).ToList(); // 结果:['+', '-', '*']
二、不用switch case实现动态复合赋值(类似g h=5的效果)
C#本身不支持直接把char变量当成运算符语法用,但我们可以用字典映射委托的方式实现动态运算,完全避开switch/case,还易扩展:
方法1:基础版(用Func映射计算逻辑)
把每个运算符对应的计算逻辑存到字典里,然后动态调用:
// 初始化运算符到计算逻辑的映射 var operatorLogic = new Dictionary<char, Func<int, int, int>> { { '+', (current, value) => current + value }, { '-', (current, value) => current - value }, { '*', (current, value) => current * value }, { '/', (current, value) => value == 0 ? throw new DivideByZeroException() : current / value } }; // 测试代码 int g = 10; char h = '/'; int operand = 2; // 先验证运算符是否合法,再执行运算 if (operatorLogic.TryGetValue(h, out var calculate)) { g = calculate(g, operand); // 等价于 g /=2,结果是5 } else { throw new ArgumentException($"不支持的运算符:{h}"); }
方法2:扩展方法版(模拟g j=5的语法感)
如果想要更接近你想象的简洁语法,可以封装成扩展方法,调用起来非常直观:
public static class IntOperatorExtensions { // 静态字典存运算符逻辑,只初始化一次 private static readonly Dictionary<char, Func<int, int, int>> _operatorMap = new() { { '+', (a,b) => a + b }, { '-', (a,b) => a - b }, { '*', (a,b) => a * b }, { '/', (a,b) => b == 0 ? throw new DivideByZeroException() : a / b } }; // 扩展方法:给int类型加一个动态运算的方法 public static void ApplyOperator(this ref int target, char op, int value) { if (!_operatorMap.TryGetValue(op, out var calc)) { throw new InvalidOperationException($"运算符 {op} 不被支持"); } target = calc(target, value); } } // 使用的时候就像这样(非常接近你想要的`g j=5`): int g = 15; char h = '*'; g.ApplyOperator(h, 3); // 等价于 g *=3,结果是45
为什么不用switch case?
这种字典映射的方式,比switch case更易维护——要加新运算符(比如取模%),直接在字典里加一行就行,不用改一堆case;同时也更灵活,甚至可以在运行时动态修改映射逻辑。
内容的提问来源于stack exchange,提问作者SourceSurfer
相关产品推荐
相关产品推荐

