C#新手遭遇CS8600/CS8604空引用警告,求解决方案
我是C#新手,正在完成一项作业,需求是获取两种杂货的名称、数量、单价并以列表形式展示。编写代码后出现了CS8600和CS8604空引用相关警告,单独查询错误代码未找到详尽解释,附上代码及错误信息,希望得到解决建议与指导。
代码
using System; public class Assignment1B { public static void Main(string[] args) { string item_one, itemtwo; int itemone_quantity, itemtwo_quantity; float itemone_cost, itemtwo_cost, itemone_total, itemtwo_total; // 询问第一个商品 Console.Write("What are you buying? "); item_one = Console.ReadLine(); Console.Write("How many? "); itemone_quantity = int.Parse(Console.ReadLine()); Console.Write("What do they cost? "); itemone_cost = float.Parse(Console.ReadLine()); Console.WriteLine(); // 询问第二个商品 Console.Write("What else are you buying? "); itemtwo = Console.ReadLine(); Console.Write("How many? "); itemtwo_quantity = int.Parse(Console.ReadLine()); Console.Write("What do they cost? "); itemtwo_cost = float.Parse(Console.ReadLine()); Console.WriteLine(); // 计算总价 itemone_total = itemone_quantity * itemone_cost; itemtwo_total = itemtwo_quantity * itemtwo_cost; // 打印清单 Console.WriteLine("Your list:"); Console.WriteLine("--------"); Console.WriteLine("{0} ({1})", item_one, itemone_quantity); Console.WriteLine("{0} ({1})", itemone_cost, itemone_total); Console.WriteLine(); Console.WriteLine("{0} ({1})", itemtwo, itemtwo_quantity); Console.Write("{0} ({1})", itemtwo_cost, itemtwo_total); } }
错误信息
item_one = Console.ReadLine(); 警告 CS8600: 将 null 文本或可能的 null 值转换为非 nullable 类型
itemone_quantity = int.Parse(Console.ReadLine()); 警告 CS8604: 参数 's' 可能为 null 引用,该参数对应 'int int.Parse(string s)'
itemone_cost = float.Parse(Console.ReadLine()); 警告 CS8604: 参数 's' 可能为 null 引用,该参数对应 'float float.Parse(string s)'
itemtwo = Console.ReadLine(); 警告 CS8600: 将 null 文本或可能的 null 值转换为非 nullable 类型
itemtwo_quantity = int.Parse(Console.ReadLine()); 警告 CS8604: 参数 's' 可能为 null 引用,该参数对应 'int int.Parse(string s)'
itemtwo_cost = float.Parse(Console.ReadLine()); 警告 CS8604: 参数 's' 可能为 null 引用,该参数对应 'float float.Parse(string s)'
错误原因
- CS8600:C# 8.0及以上默认启用可空引用类型检查,
Console.ReadLine()在用户按下Ctrl+Z(Windows)或Ctrl+D(Linux/macOS)时会返回null,而你把这个可能为null的值赋值给了非可空的string变量,编译器判定存在空引用风险。 - CS8604:
int.Parse和float.Parse要求传入非空字符串,直接把可能为null的Console.ReadLine()结果传进去,一旦出现null就会触发空引用异常,所以编译器发出警告。
解决方法
1. 处理输入null的情况
先读取输入到可空字符串变量,再检查是否为null或空字符串,不符合要求就提示用户:
// 获取商品名称示例 Console.Write("What are you buying? "); string? input = Console.ReadLine(); if (string.IsNullOrEmpty(input)) { Console.WriteLine("输入不能为空,请重新运行程序。"); return; } item_one = input;
2. 使用安全的解析方法
放弃Parse改用TryParse,它能同时处理null和无效输入(比如非数字字符),还不会抛出异常:
// 获取数量示例 Console.Write("How many? "); input = Console.ReadLine(); while (!int.TryParse(input, out itemone_quantity)) { Console.WriteLine("请输入有效的数字!"); Console.Write("How many? "); input = Console.ReadLine(); }
单价同理,把int.TryParse换成float.TryParse即可。
3. 临时禁用警告(应急用,不推荐)
如果只是为了作业快速消除警告,不想做输入验证,可以在代码最顶部添加:
#pragma warning disable CS8600, CS8604
但这只是隐藏警告,程序遇到null输入还是会崩溃,不建议实际项目中使用。
优化建议
把重复的输入逻辑封装成方法,减少代码冗余,比如:
static string GetNonEmptyString(string prompt) { Console.Write(prompt); string? input; do { input = Console.ReadLine(); } while (string.IsNullOrEmpty(input)); return input; } static int GetIntInput(string prompt) { int result; string? input; do { Console.Write(prompt); input = Console.ReadLine(); } while (!int.TryParse(input, out result)); return result; }
之后调用这些方法获取输入,代码会更简洁易维护。
内容的提问来源于stack exchange,提问作者maail preston

