0

I have a few classes that implement the ITerminalCommand interface:

public class TerminalCommandHelp : MonoBehaviour, ITerminalCommand { //... }
public class TerminalCommandExit : MonoBehaviour, ITerminalCommand { //... }

In a separate class, I would like to be able to look up a string in a dictionary and create a new instance of the ITerminalCommand, but I don't know how I would go about doing this, so below I have written some sort of pseudo-code in the hopes that someone might understand what I am trying to do.

Dictionary<string, ITerminalCommand> validInputs = new Dictionary<string, ITerminalCommand>()
    {
        {
            "help", 
            //Some reference to the TerminalCommandHelp class so I can instantiate it at my own will
        },

        {   
            "exit",
            //Some reference to the TerminalCommandExit class so I can instantiate it at my own will
        }
    };

    //Create a new object based on the key I am looking up, and supply some arguments to the constructor
     ITerminalCommand genericTerminalCommand = new validInputs["help"](arguments);

    //Run a method on the newly instantiated object
    genericTerminalCommand.Execute();

How can I 'abstractly' reference a class type in a dictionary so I can instantiate it and also supply some arguments to it?

Vranvs
  • 1,411
  • 4
  • 17
  • 38
  • Why not just store instances of the classes in the dictionary? – Rufus L Aug 03 '20 at 20:02
  • I could, but then each time I want to use the class I have to remove the data that was previously inputted in it. I think I would prefer to create a new object each time... unless that is a dumb thing to do. – Vranvs Aug 03 '20 at 20:03
  • Didn't you ask the [similar question](https://stackoverflow.com/questions/63235332/c-using-a-dictionary-of-string-interface-to-reference-different-classes) already? – Pavel Anikhouski Aug 03 '20 at 20:03
  • I did, and their solution was what Rufus mentioned above -- to get a reference to an already-instantiated object. What I want to do though is instantiate that 'type', rather than modify an existing one – Vranvs Aug 03 '20 at 20:05
  • Are you familiar with [`Activator.CreateInstance`](https://learn.microsoft.com/en-us/dotnet/api/system.activator.createinstance?view=netcore-3.1)? It sounds like what you're looking for. – Rufus L Aug 03 '20 at 20:08
  • Why did you accept an answer if it doesn't work for what you want? Also, don't post duplicate questions – Camilo Terevinto Aug 03 '20 at 20:11
  • 1
    I'd just `Dictionary> validInputs = new Dictionary> { { "help", () => new TerminalCommandHelp() } };` – Camilo Terevinto Aug 03 '20 at 20:13
  • @CamiloTerevinto Sorry officer!! The way I worded my question, it was the right solution. This question has been re-worded to better explain my problem. Still new to C#, sorry for causing a catastrophe. – Vranvs Aug 03 '20 at 20:23

1 Answers1

1

Try this code:

Dictionary<string, Type> validInputs = new Dictionary<string, Type>()
{
    { "help", typeof(TerminalCommandHelp) },
    { "exit", typeof(TerminalCommandExit) },
};

ITerminalCommand genericTerminalCommand = (ITerminalCommand)Activator.CreateInstance(validInputs["help"]);
Sherif Elmetainy
  • 4,034
  • 1
  • 13
  • 22
  • How would one pass arguments into the constructor? I read that you can just append them after the Type argument, but CreateInstance() is overloaded to accept multiple different things and I don't want to conflict with those – Vranvs Aug 03 '20 at 20:41
  • You just pass them after the type, *in the order that they appear in your type's constructor*. If you only provide the `Type` and parameters, then you're using [`this overload`](https://learn.microsoft.com/en-us/dotnet/api/system.activator.createinstance#System_Activator_CreateInstance_System_Type_System_Object___) of `CreateInstance`. – Joshua Robinson Aug 03 '20 at 21:23