You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LinkedList.First.Value返回null但链表非空的异常问题求助

问题:LinkedList.First.Value返回NullReferenceException的解决办法

问题描述

开发控制台蛇游戏时,调用LinkedList.First.Value抛出NullReferenceException,提示LinkedList.First.get返回null。但已给链表首个元素设置了55,确认链表非空。

相关代码片段

链表定义

LinkedList<int> Pos = new LinkedList<int>();

Main方法代码

var p = new Program();
p.Pos.AddLast(55);
Timer myTimer = new Timer();
myTimer.Elapsed += new ElapsedEventHandler(Move);
myTimer.Interval = 1000; // 1000毫秒为1秒
myTimer.Start();

引发错误的Move方法代码

p.Pos.AddFirst(p.Pos.First.Value + p.dir);

异常信息

System.NullReferenceException: 'Object reference not set to an instance of an object.'
System.Collections.Generic.LinkedList.First.get returned null.

完整代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using System.Collections;

namespace Snake
{
    class Program
    {
        LinkedList<int> Pos = new LinkedList<int>();
        int dir = 1;
        bool snakeAlive = true;
        static void Main(string[] args)
        {
            var p = new Program();
            p.Pos.AddLast(55);
            Timer myTimer = new Timer();
            myTimer.Elapsed += new ElapsedEventHandler(Move);
            myTimer.Interval = 1000; // 1000 ms is one second
            myTimer.Start();
            do
            {
                switch (Console.ReadKey().Key)
                {
                    case ConsoleKey.UpArrow:
                        p.dir = -10;
                        break;
                    case ConsoleKey.DownArrow:
                        p.dir = 10;
                        break;
                    case ConsoleKey.LeftArrow:
                        p.dir = -1;
                        break;
                    case ConsoleKey.RightArrow:
                        p.dir = 1;
                        break;
                }
            } while (p.snakeAlive == true);
        }

        void drawGame()
        {
            Console.Clear();
            for (int i = 0; i < 100; i++)
            {
                if (i % 10 == 9)
                {
                    Console.WriteLine(IsSnake(Pos, i));
                }
                else
                {
                    Console.Write(IsSnake(Pos, i));
                }
            }
        }
        String IsSnake(LinkedList<int> sPos, int position)
        {
            for (int i = 0; i < sPos.Count; i++)
            {
                if (position == sPos.ElementAt(i))
                {
                    return "==";
                }
            }
            return "[]";
        }
        public static void Move(object source, ElapsedEventArgs e)  {
            var p = new Program();
                p.Pos.AddFirst(p.Pos.First.Value + p.dir);
                p.Pos.RemoveLast();
            p.drawGame();
        }
    }
}

问题原因与解决方案

原因分析

错误核心在Move方法:

public static void Move(object source, ElapsedEventArgs e)  {
    var p = new Program(); // 新建了一个全新的Program实例
    p.Pos.AddFirst(p.Pos.First.Value + p.dir);
    // ...
}

Main方法中创建的p是已初始化Pos的游戏实例,但Move方法里重新创建了一个Program实例,这个新实例的Pos链表是空的,调用First.Value必然抛出空引用异常。

解决方案

  1. 传递正确的实例到Move方法
    修改Timer事件注册逻辑,用lambda捕获Main中的p实例,同时将Move改为非静态方法:

    // Main方法中修改事件注册
    myTimer.Elapsed += (source, e) => p.Move(source, e);
    
    // 修改Move方法为非静态
    public void Move(object source, ElapsedEventArgs e)  {
        Pos.AddFirst(Pos.First.Value + dir);
        Pos.RemoveLast();
        drawGame();
    }
    

    这样Move操作的就是Main中已初始化的游戏实例,不会再出现空链表问题。

  2. 额外优化建议

    • IsSnake方法用ElementAt遍历LinkedList效率极低,LinkedList不支持索引访问,改为遍历节点:
      String IsSnake(LinkedList<int> sPos, int position)
      {
          foreach (var pos in sPos)
          {
              if (pos == position)
              {
                  return "==";
              }
          }
          return "[]";
      }
      
    • 按键读取时添加Console.ReadKey(true),避免按键字符显示在控制台,提升游戏体验。

内容的提问来源于stack exchange,提问作者Leo Barber

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 23:31:37