C#中解析int与枚举时如何对多值进行错误验证?
解决C#中int与枚举解析的错误验证及代码冗余问题
嘿,作为C#新手碰到这种解析验证的问题太正常啦!我来帮你梳理下怎么既做好错误检查,又让代码干净不冗余~
先看你原来的代码:
int.TryParse(coordinates[0], out int x); int.TryParse(coordinates[1], out int y); Direction d = (Direction)Enum.Parse(typeof(Direction), coordinates[2]);
这里有两个明显的问题:一是int.TryParse返回了成功/失败的布尔值,但你没处理失败的情况;二是Enum.Parse如果输入不合法会直接抛出异常,不够安全,而且重复的解析逻辑显得啰嗦。
1. 先把枚举解析改成安全模式
别用Enum.Parse了,换成**Enum.TryParse**,它和int.TryParse一样返回布尔值表示解析是否成功,不会直接炸锅。用法示例:
if (!Enum.TryParse(coordinates[2], out Direction d)) { // 处理解析失败的情况,比如给用户提示 Console.WriteLine($"无效的方向:{coordinates[2]},请输入{string.Join(", ", Enum.GetNames(typeof(Direction)))}中的一个"); return; // 或者抛出自定义异常,看你项目需求来 }
额外提醒:最好再加个Enum.IsDefined判断,防止输入的是枚举范围内的数字但不是定义好的枚举值,比如你的Direction没定义5,但用户输入5时TryParse会成功,这时候就需要过滤:
if (!Enum.TryParse(coordinates[2], out Direction d) || !Enum.IsDefined(typeof(Direction), d)) { // 错误处理逻辑 }
2. 封装int解析逻辑减少冗余
你要解析两个int(x和y),重复写TryParse加判断太啰嗦,封装个小方法复用就好:
private static bool TryParseInt(string input, out int result, out string errorMsg) { if (int.TryParse(input, out result)) { errorMsg = null; return true; } errorMsg = $"「{input}」不是有效的整数"; return false; }
这样解析x和y的时候就可以统一调用:
if (!TryParseInt(coordinates[0], out int x, out string xError)) { Console.WriteLine(xError); return; } if (!TryParseInt(coordinates[1], out int y, out string yError)) { Console.WriteLine(yError); return; }
3. 整合所有解析逻辑,让代码更整洁
如果你的项目需要批量验证多个字段,可以把所有解析逻辑放在一起,收集错误信息再统一输出,用户体验更好:
// 先假设你的Direction枚举是这样的 enum Direction { Up, Down, Left, Right } public bool TryParseCoordinates(string[] coordinates, out int x, out int y, out Direction direction, out List<string> errors) { x = 0; y = 0; direction = default; errors = new List<string>(); // 先验证输入的数组长度是否符合要求 if (coordinates.Length != 3) { errors.Add("需要输入三个值:X坐标、Y坐标、方向"); return false; } // 解析X坐标 if (!int.TryParse(coordinates[0], out x)) { errors.Add($"X坐标「{coordinates[0]}」不是有效的整数"); } // 解析Y坐标 if (!int.TryParse(coordinates[1], out y)) { errors.Add($"Y坐标「{coordinates[1]}」不是有效的整数"); } // 解析方向枚举 if (!Enum.TryParse(coordinates[2], out direction) || !Enum.IsDefined(typeof(Direction), direction)) { errors.Add($"方向「{coordinates[2]}」无效,可选值:{string.Join(", ", Enum.GetNames(typeof(Direction)))}"); } // 没有错误就返回true,否则返回false return errors.Count == 0; }
调用这个方法的时候就可以这样用:
// 假设coordinates是用户输入的字符串数组 string[] coordinates = {"10", "20", "Up"}; if (!TryParseCoordinates(coordinates, out int x, out int y, out Direction d, out List<string> errors)) { Console.WriteLine("解析失败:"); foreach (var error in errors) { Console.WriteLine($"- {error}"); } } else { // 解析成功,做后续业务逻辑 Console.WriteLine($"解析成功:X={x}, Y={y}, 方向={d}"); }
额外小技巧:用C#元组简化返回(可选)
如果不想写太多out参数,也可以用元组把结果打包返回:
private static (bool IsSuccess, int? X, int? Y, Direction? Direction, List<string> Errors) ParseCoordinates(string[] coordinates) { var errors = new List<string>(); int? x = null; int? y = null; Direction? direction = null; // 同样的验证逻辑... return (errors.Count == 0, x, y, direction, errors); }
调用时:
var parseResult = ParseCoordinates(coordinates); if (!parseResult.IsSuccess) { // 处理错误 } else { // 使用parseResult.X、parseResult.Y等 }
这样既完成了严谨的错误验证,又避免了重复代码,逻辑也清晰很多~
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

