-2

So I am having some trouble referencing a dictionary. I am trying to make an economy discord bot. I want the user to setup the dictionary with the command !g setup, then type !g register to register their Discord ID to the dictionary.

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Discord.Commands;
using Discord;

namespace Games_Bot.Modules
{
    public class Commands : ModuleBase<SocketCommandContext>
    {
        public Dictionary<ulong, int> economy;

        [Command("g setup")]
        public async Task Setup()
        {
            economy = new Dictionary<ulong, int>();
        }

        [Command("g register")]
        public async Task Register()
        {
            var userInfo = Context.User;
            try
            {
                if (economy.ContainsKey(userInfo.Id) == false) { economy.Add(userInfo.Id, 0); }
            }
            catch { return; }
        }
    }
}

Whenever I try to reference the dictionary in Register(), Visual Studio throws me a null error. Any help is appreciated!

  • I know what a null reference is. I just don't understand how this case is a null reference. I tell the dictionary type and give it a name, then I assign it a value. – Pixelated Lagg Jul 01 '21 at 01:36
  • 1
    @PixelatedLagg Presumably a new instance of `Commands` is created each time. I expect you issue the setup command, an instance of `Commands` gets created, the `Setup()` method runs. Next, you issue the register command, a new instance of `Commands` gets created, and the `Register()` method runs. – ProgrammingLlama Jul 01 '21 at 01:45
  • The reason I don't declare dictionary outside the void is because every time you call on a command, the whole script is called on again and it would just re-declare the dictionary each time. – Pixelated Lagg Jul 01 '21 at 01:51
  • Re-read my comment carefully. – ProgrammingLlama Jul 01 '21 at 01:53
  • I only know that the whole script gets called on again - I don't know if an instance gets created each time, I'm not that familiar with Discord.Net. If you are correct and the whole script gets initialized again, how would I go about declaring and adding values to a dictionary? – Pixelated Lagg Jul 01 '21 at 01:59
  • I'm not familiar with Discord.Net at all, but the behaviour you've described is congruent with that. Are you using dependency injection? – ProgrammingLlama Jul 01 '21 at 02:00
  • There is no need to use `ContainsKey` and `Add`. Just call `TryAdd`. Or, even better, use a `ConcurrentDictionary`. – mjwills Jul 01 '21 at 02:06

1 Answers1

-1

I'm going to assume you called Setup, something you didn't claim. If so, then I presume a new instance of Commands is create for each request. As such, you could use

public class Commands : ModuleBase<SocketCommandContext>
{
    public static Dictionary<ulong, int> economy = new Dictionary<ulong, int>();

    [Command("g register")]
    public async Task Register()
    {
        var userInfo = Context.User;
        try
        {
            if (economy.ContainsKey(userInfo.Id) == false) { economy.Add(userInfo.Id, 0); }
        }
        catch { return; }
    }
}

Note the static modifier.

(I'm not familiar with the library in question. I use DSharpPlus for my bot.)

ikegami
  • 367,544
  • 15
  • 269
  • 518