Search code examples
c#typesenumsinstantiation

C# dynamically instantiate Type from Enum


I am a C# beginner. I hope you have patience with me. Lets say I have an enum

public enum Dogs
{
    Terrier,
    Poodle,
    Pitbull,
}

and some dog classes

public class Terrier {
}

public class Poodle {
}

public class Pitbull {
}

And I for some reason want to instantiate each of the classes dynamically from their types (enum values),

        foreach(Dogs d in Enum.GetValues(typeof(Dogs)))
        {
            // d myDog = new d();
            // "...is a variable but is used like a type"
        }

I have also tried with

var myDog = Activator.CreateInstance(d);
// "...cannot convert from namespace.Dogs to System.Type"

Solution

  • Don't use an enum for that. A much saner solution is an array of Types:

    private static Type[] dogs =
    {
        typeof(Terrier),
        typeof(Poodle),
        typeof(Pitbull),
    }
    

    Then you can still go over them all:

    foreach (Type type in dogs)
    {
        Object dog = Activator.CreateInstance(type);
    }
    

    Though unless you're only using .ToString() on it, you might want to give those classes a common interface or superclass to inherit (as rfmodulator also said in his answer) so you can actually call functions on the resulting objects. If all three inherit from a Dog superclass, which makes them share a common Bark() method, you can at least do something like this:

    public abstract class Dog
    {
        String Bark();
    }
    
    public class Terrier : Dog
    {
        public override String Bark() { return "Woof!"; }
    }
    
    public class Poodle : Dog
    {
        public override String Bark() { return "Yap"; }
    }
    
    public class Pitbull : Dog
    {
        public override String Bark() { return "Whuff!"; }
    }
    

    ...so you can actually get something useful out of your instantiated objects:

    foreach (Type type in dogs)
    {
        Dog dog = (Dog)Activator.CreateInstance(type);
        Console.WriteLine(dog.Bark());
    }
    

    The only slight downside to this method, from a design perspective, is that there's no way to enforce that only sub-types of Dog can be put in the Type[] dogs array; technically, any type object can be put in there. So that's the programmer's responsibility to not mess that up.