Discord.Interactions框架SlashCommand斜杠命令重载实现方案
问题原因
Discord 斜杠命令本身要求同作用域下命令名称唯一,Discord.Interactions 库不支持通过C#方法重载的方式注册同名命令,重复给同名方法加[SlashCommand]特性就会触发你看到的如下异常:
System.InvalidOperationException: A Discord.Interactions.SlashCommandInfo already exists with the same name: quote
无自定义参数解析的实现方案
直接在单个斜杠命令方法里定义可选参数,框架会自动识别可选参数生成Discord端的命令选项,你只需要在方法内部根据参数是否传入走不同逻辑即可,不需要手写任何参数解析逻辑。
修正后的可运行代码如下:
using Discord.Interactions; using Newtonsoft.Json; namespace MyBot { public class Quotes : InteractionModuleBase<SocketInteractionContext> { private static readonly QuoteData[] _quotes; private static readonly Random _rng = new(); static Quotes () { var json = File.ReadAllText(Path.Combine("Data", "quotes.json")); _quotes = JsonConvert.DeserializeObject<QuoteData[]>(json)!; } [SlashCommand("quote", "获取名言,传入序号可查询指定名言,不传则随机返回")] public async Task Quote( [Summary(description: "名言序号,传入则返回对应序号的内容")] int? index = null ) { // 未传参时走随机返回逻辑 if (!index.HasValue) { var randomResult = _quotes[_rng.Next(_quotes.Length)]; await RespondAsync(randomResult.Text); return; } // 传了序号参数时走指定查询逻辑 if (index.Value > 0 && index.Value <= _quotes.Length) { // 修复原代码的语法笔误 await RespondAsync(_quotes[index.Value - 1].Text); } else { await RespondAsync("We don't have a quote with that number."); } } } }
方案说明
- 用可空值类型
int?给参数设置默认值null,框架会自动将这个参数识别为非必填的命令选项,用户在Discord端输入/quote时可以选择填或者不填序号参数,完全匹配你原本想要的两种调用效果 - 所有参数的类型校验、绑定解析全由
Discord.Interactions框架自动完成,不需要你手动处理交互 payload 的解析逻辑 - 命令只注册一次,不会触发重名异常
内容的提问来源于stack exchange,提问作者Mason Wheeler
相关产品推荐
相关产品推荐

