如何避免控制台输入时发生类型转换错误?
- 内容介绍
- 相关推荐
本文共计833个文字,预计阅读时间需要4分钟。
控制台读取用户输入时,最易出现的类型转换异常基本原因在于 Console.ReadLine() 只返回字符串,而后续直接使用 int.Parse()、DateTime.Parse() 等方法进行强转。一旦用户输入格式错误(如字母代替数字、日期格式不正确),程序将立即崩溃。
优先用 TryParse 替代 Parse
这是最直接有效的预防手段。TryParse 不抛异常,而是返回 bool 值表示是否转换成功,并通过 out 参数输出结果。
-
✅ 推荐写法:
string input = Console.ReadLine();<br>if (int.TryParse(input, out int year))<br>{<br> // year 已是有效整数,可安全使用<br> Console.WriteLine($"{year} 是闰年吗?" + (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)));<br>}<br>else<br>{<br> Console.WriteLine("请输入一个有效的年份(纯数字)");<br>}
-
❌ 避免写法:
int year = int.Parse(Console.ReadLine()); // 用户输"a"就直接报 FormatException
对日期等复杂类型做格式预校验
日期字符串格式多变(“2026-04-15”、“2026/04/15”、“15-Apr-2026”),单纯靠 TryParse(DateTime) 容易失败或误判。建议明确约定格式,并用带格式的 TryParseExact。
- 指定一种输入格式,比如只接受 yyyy-MM-dd:
string dateStr = Console.ReadLine();<br>if (DateTime.TryParseExact(dateStr, "yyyy-MM-dd", null, DateTimeStyles.None, out DateTime dt))<br>{<br> Console.WriteLine($"解析成功:{dt:yyyy年MM月dd日}");<br>}<br>else<br>{<br> Console.WriteLine("日期格式错误,请输入如 2026-04-15");<br>}
- 支持多种格式时,传入字符串数组:
string[] formats = { "yyyy-MM-dd", "yyyy/MM/dd", "dd-MM-yyyy" };<br>DateTime.TryParseExact(input, formats, null, DateTimeStyles.None, out dt);
提前清理和规范化输入
用户可能无意中输入空格、制表符甚至全角字符。不处理这些干扰,即使内容正确也可能导致 TryParse 失败。
- 用 Trim() 去首尾空白:
string input = Console.ReadLine()?.Trim();
- 对数字类输入,可进一步过滤非数字字符(谨慎使用,仅限纯数字场景):
string cleanInput = new string(input.Where(char.IsDigit).ToArray());
- 对日期类输入,可替换常见分隔符为统一符号:
input = input.Replace('/', '-').Replace('.', '-');
结合类型检查与安全转换(针对对象引用)
如果从控制台读取的是序列化数据(如 JSON 字符串),再反序列化为对象,后续又需转型(如 object → Person),此时要防 InvalidCastException。
- 不用 (Person)obj,改用 as 操作符:
Person p = obj as Person;<br>if (p != null)<br>{<br> // 安全使用 p<br>}
- 或用 is 判断后再转:
if (obj is Person person)<br>{<br> // person 已是 Person 类型,无需再 cast<br>}
本文共计833个文字,预计阅读时间需要4分钟。
控制台读取用户输入时,最易出现的类型转换异常基本原因在于 Console.ReadLine() 只返回字符串,而后续直接使用 int.Parse()、DateTime.Parse() 等方法进行强转。一旦用户输入格式错误(如字母代替数字、日期格式不正确),程序将立即崩溃。
优先用 TryParse 替代 Parse
这是最直接有效的预防手段。TryParse 不抛异常,而是返回 bool 值表示是否转换成功,并通过 out 参数输出结果。
-
✅ 推荐写法:
string input = Console.ReadLine();<br>if (int.TryParse(input, out int year))<br>{<br> // year 已是有效整数,可安全使用<br> Console.WriteLine($"{year} 是闰年吗?" + (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)));<br>}<br>else<br>{<br> Console.WriteLine("请输入一个有效的年份(纯数字)");<br>}
-
❌ 避免写法:
int year = int.Parse(Console.ReadLine()); // 用户输"a"就直接报 FormatException
对日期等复杂类型做格式预校验
日期字符串格式多变(“2026-04-15”、“2026/04/15”、“15-Apr-2026”),单纯靠 TryParse(DateTime) 容易失败或误判。建议明确约定格式,并用带格式的 TryParseExact。
- 指定一种输入格式,比如只接受 yyyy-MM-dd:
string dateStr = Console.ReadLine();<br>if (DateTime.TryParseExact(dateStr, "yyyy-MM-dd", null, DateTimeStyles.None, out DateTime dt))<br>{<br> Console.WriteLine($"解析成功:{dt:yyyy年MM月dd日}");<br>}<br>else<br>{<br> Console.WriteLine("日期格式错误,请输入如 2026-04-15");<br>}
- 支持多种格式时,传入字符串数组:
string[] formats = { "yyyy-MM-dd", "yyyy/MM/dd", "dd-MM-yyyy" };<br>DateTime.TryParseExact(input, formats, null, DateTimeStyles.None, out dt);
提前清理和规范化输入
用户可能无意中输入空格、制表符甚至全角字符。不处理这些干扰,即使内容正确也可能导致 TryParse 失败。
- 用 Trim() 去首尾空白:
string input = Console.ReadLine()?.Trim();
- 对数字类输入,可进一步过滤非数字字符(谨慎使用,仅限纯数字场景):
string cleanInput = new string(input.Where(char.IsDigit).ToArray());
- 对日期类输入,可替换常见分隔符为统一符号:
input = input.Replace('/', '-').Replace('.', '-');
结合类型检查与安全转换(针对对象引用)
如果从控制台读取的是序列化数据(如 JSON 字符串),再反序列化为对象,后续又需转型(如 object → Person),此时要防 InvalidCastException。
- 不用 (Person)obj,改用 as 操作符:
Person p = obj as Person;<br>if (p != null)<br>{<br> // 安全使用 p<br>}
- 或用 is 判断后再转:
if (obj is Person person)<br>{<br> // person 已是 Person 类型,无需再 cast<br>}

