C#开发Discord.NET机器人触发Object reference not set报错求助
问题根因
你抛出空引用异常的核心原因是MessageHandler类中实例化了未完成登录初始化的新DiscordSocketClient对象:
- Program类中已经创建了一个调用过
LoginAsync、StartAsync完成登录的客户端实例,这个实例的CurrentUser才会有有效值 - MessageHandler中每触发一次消息事件就new一个新的
DiscordSocketClient,这个新实例从未执行登录流程,CurrentUser属性默认为null,访问时直接抛出空引用异常。
修复方案
1. 修改MessageHandler类,通过构造函数注入已初始化的客户端实例
using System; using System.Threading.Tasks; using Discord; using Discord.WebSocket; namespace ConsoleApp1 { public class MessageHandler { private readonly DiscordSocketClient _client; // 接收外部传入的已完成登录的客户端实例,不再自行实例化 public MessageHandler(DiscordSocketClient client) { _client = client; } public async Task MessageReceived(SocketMessage message) { // 增加空值判断,过滤无发送者的系统消息,避免极端情况空引用 if (message.Author == null || _client.CurrentUser == null) return; var founder = message.Author.Username; if (founder != _client.CurrentUser.Username) { var channel = message.Channel; await channel.SendMessageAsync("Hello"); } } } }
2. 修改Program类,传入已初始化的客户端实例,调整事件绑定时机
public async Task MainAsync() { _client = new DiscordSocketClient(); _client.Log += new Logger().Log; // 事件绑定提前到客户端启动前,避免漏掉启动初期触发的事件 _client.Ready += OnReady; // 把当前已初始化的客户端实例传给MessageHandler _client.MessageReceived += new MessageHandler(_client).MessageReceived; await _client.LoginAsync(TokenType.Bot, token); await _client.StartAsync(); await Task.Delay(-1); }
空引用异常通用排查方向
- 异常抛出后先通过调试断点定位到具体代码行,逐行检查该行所有引用类型对象是否为null
- 第三方SDK的实例属性需要确认完成对应初始化流程后再访问,不要直接访问刚new出来的未初始化实例的属性
- 跨类共用的全局实例优先通过构造函数注入传递,不要在业务类中重复实例化核心对象
内容的提问来源于stack exchange,提问作者Niveus
相关产品推荐
相关产品推荐

