C# 从文本文件创建Livestock对象时出现System.NullReferenceException空引用异常
空引用报错的根本原因排查
你遇到的System.NullReferenceException根本不是什么“对象创建失败、引用丢失”的玄学问题,全是代码笔误和逻辑错位导致的硬伤,逐点列清楚:
1. 最致命的循环条件笔误
你写的两处内层for循环全是这个写法:
for (int i = 0; i > 20; i++)
这个循环从初始化阶段就永远不会执行:i从0开始,第一次判断0 > 20就是假值,循环体一行代码都跑不到。
直接后果就是你初始化的livestocks数组,20个元素全是引用类型默认的null值——这时候不管你调用哪个数组元素的方法,比如livestocks[9].GetID(),百分百触发空引用,根本没有例外。
2. 赋值逻辑完全错位
按照任务要求“每行文本对应一个独立对象实例”,正确的实现逻辑非常简单:
- 数组创建完成后,在外层维护一个下标计数器
- 每读一行文本、解析完所有字段、new出一个Livestock实例,就把这个实例放到数组的当前下标位置,计数器+1
- 全程根本不需要在读行的循环里,再嵌一个遍历整个数组的for循环
你现在的逻辑相当于想:每读一行文本,就把这行对应的同一个对象,塞给数组里的20个位置——就算你把之前的循环条件改对了,最终结果也会是整个数组所有元素全指向同一个Livestock实例,完全不符合“每行对应独立对象”的要求。
3. 冗余判断制造额外报错点
你写的判断if (_livestockType != null )没有任何实际意义:这个值是你通过Split(',')拆分得到的字符串,只要文件行格式正常,这个字符串永远不会是null,等于这个判断永远成立,else分支根本进不去。
更离谱的是else分支的代码:两个分支的对象创建逻辑写的完全一模一样,没有任何区分,还在else里直接调用livestocks[9].GetID()——这时候数组里全是null,哪怕你能进到这个分支,照样会触发空引用。
修正后的核心代码参考
直接删掉两个没用的内层for循环,把核心逻辑改成下面的写法就行:
Livestock[] livestocks = new Livestock[20]; // 在外层定义数组下标计数器,不要把赋值逻辑藏在内层循环里 int arrayIndex = 0; try { // 用using包裹StreamReader,不用手动关文件 using (TextReader textReader = new StreamReader(@"C:\...file.txt")) { string textLine; // 读行的同时限制下标不超过数组长度,防止越界 while ((textLine = textReader.ReadLine()) != null && arrayIndex < 20) { var livestockContent = textLine.Split(','); // 字段解析的逻辑和你原来写的完全一致,不用改 int _ID = int.Parse(livestockContent[0]); string _livestockType = livestockContent[1]; int _yearBorn = int.Parse(livestockContent[2]); double _costPerMonth = double.Parse(livestockContent[3], CultureInfo.InvariantCulture); double _costPerVaccination = double.Parse(livestockContent[4], CultureInfo.InvariantCulture); double _amountOfMilk = double.Parse(livestockContent[5], CultureInfo.InvariantCulture); // 直接把新创建的实例放到当前下标位置,不需要额外循环 livestocks[arrayIndex] = new Livestock(_ID, _livestockType, _yearBorn, _costPerMonth, _costPerVaccination, _amountOfMilk); // 下标后移,给下一行的对象留位置 arrayIndex++; } } } catch (FileNotFoundException ex) { Console.WriteLine(ex.Message); }
改完之后调试的时候展开livestocks数组就能看到,每个位置都会存对应的Livestock实例,不会再出现空引用问题。
内容的提问来源于stack exchange,提问作者TakToJa
相关产品推荐
相关产品推荐

