BadmintonCat
BadmintonCat

Reputation: 9576

How to create instances of type declarations?

I want to store a class declaration in a struct and later instantiate new objects from that class but I'm running into a few obstacles. I know how to do this in a few other languages but in C# I didn't have any success yet.

abstract class Command
{
    // Base class for all concrete command classes.
}

class FooCommand : Command
{
}

class ListCommand : Command
{
}

Now I want to have a struct that stores some data and a Command subclass class ref:

struct CommandVO
{
    string trigger;
    string category;
    Type commandClass;
}

Somewhere else later on I want to fetch the VO structs from a dictionary and create concrete command objects:

var commandMap = new Dictionary<string, CommandVO?>(100);
commandMap.Add("foo", new CommandVO
{
    trigger = "foo", category = "foo commands", commandClass = FooCommand
});
commandMap.Add("list", new CommandVO
{
    trigger = "list", category = "list commands", commandClass = ListCommand
});

...

var commandVO = commandMap["foo"];
if (commandVO != null)
{
    var commandClass = commandVO.Value.commandClass;
    // How to instantiate the commandClass to a FooCommand object here?
}

I've checked this page for methods on how to instantiate types but since Type doesn't represent any concrete class I wonder how do I get commandClass to instantiate to a proper object of its type? And is it correct in this case to store class declarations as Type in the struct or is there a better approach?

Upvotes: 0

Views: 41

Answers (1)

Paweł Audionysos
Paweł Audionysos

Reputation: 606

You have to wrap type with typeof():

var commandMap = new Dictionary<string, CommandVO?>(100);
commandMap.Add("foo", new CommandVO {
    trigger = "foo", category = "foo commands", commandClass = typeof(FooCommand)
});

You can write extension method like this:

internal static class CommandHelper {

    internal static Command createCommand(this Dictionary<string, CommandVO?> d, string name) {
        if (!d.ContainsKey(name)) return null;
        return Activator.CreateInstance(d[name]?.commandClass) as Command;
    }

}

Than you can get your Cammand instance:

var instance = commandMap.createCommand("foo");

Upvotes: 1

Related Questions