如何重构C#中设备方法参数解析的冗长if/else语句?
重构C#反射调用的参数类型转换逻辑,消除冗余if/else
问题分析
原代码通过硬编码类型字符串的if/else判断实现参数转换,不仅代码冗余,新增类型时需重复修改逻辑,维护成本高。此外原代码存在逻辑bug:foreach循环内每次重置int i=0,导致始终只处理方法的第一个参数,需优先修正。
重构方案
方案1:使用Convert.ChangeType简化类型转换
.NET内置的Convert.ChangeType方法可直接将字符串转换为指定类型,无需逐个判断类型,代码简洁且易维护:
// 按创建时的Name排序,确保参数顺序与方法定义一致 var textBoxes = panel1.Controls.OfType<TextBox>() .OrderBy(tb => int.Parse(tb.Name)) .ToList(); var methodParams = currMethod.GetParameters(); var methodArgs = new List<object>(); for (int i = 0; i < textBoxes.Count; i++) { var textBox = textBoxes[i]; var paramType = methodParams[i].ParameterType; // 移除ref/out的引用符号,获取实际目标类型 var targetType = paramType.IsByRef ? paramType.GetElementType() : paramType; object convertedValue; try { convertedValue = targetType == typeof(string) ? textBox.Text : Convert.ChangeType(textBox.Text, targetType); methodArgs.Add(convertedValue); } catch (FormatException ex) { MessageBox.Show($"参数{i+1}格式错误:{ex.Message}"); return; } } // 调用目标方法 currMethod.Invoke(DeviceTypeAndInstance.Values.FirstOrDefault(), methodArgs.ToArray());
方案2:自定义类型转换字典(支持特殊转换逻辑)
如果需要对特定类型实现自定义转换(比如将"是/否"字符串转为bool),可预定义类型到转换函数的字典,扩展性更强:
// 预定义类型转换规则,可按需扩展 var typeConverters = new Dictionary<Type, Func<string, object>> { { typeof(short), s => short.Parse(s) }, { typeof(int), s => int.Parse(s) }, { typeof(long), s => long.Parse(s) }, { typeof(byte), s => byte.Parse(s) }, { typeof(float), s => float.Parse(s) }, { typeof(double), s => double.Parse(s) }, { typeof(bool), s => bool.Parse(s) }, { typeof(string), s => s } }; var textBoxes = panel1.Controls.OfType<TextBox>() .OrderBy(tb => int.Parse(tb.Name)) .ToList(); var methodParams = currMethod.GetParameters(); var methodArgs = new List<object>(); for (int i = 0; i < textBoxes.Count; i++) { var textBox = textBoxes[i]; var paramType = methodParams[i].ParameterType; var targetType = paramType.IsByRef ? paramType.GetElementType() : paramType; object convertedValue; try { if (typeConverters.TryGetValue(targetType, out var converter)) { convertedValue = converter(textBox.Text); } else { // 未定义转换规则时默认返回字符串,或抛出异常提示 convertedValue = textBox.Text; } methodArgs.Add(convertedValue); } catch (Exception ex) { MessageBox.Show($"参数{i+1}转换失败:{ex.Message}"); return; } } currMethod.Invoke(DeviceTypeAndInstance.Values.FirstOrDefault(), methodArgs.ToArray());
额外优化点
- 控件筛选与排序:改用
OfType<TextBox>直接筛选文本框,再按创建时设置的Name排序,确保参数顺序与方法定义一致,避免原代码遍历所有控件的低效问题。 - 错误处理:添加异常捕获,处理用户输入格式错误的情况,提升程序健壮性。
- 类型判断优化:原代码用
control.GetType().ToString()判断控件类型,改用OfType<T>更高效简洁。
内容的提问来源于stack exchange,提问作者Zayum
相关产品推荐
相关产品推荐

