Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to dynamically create an object based on the name of the enum? Without Switch

Tags:

c#

enums

I have something like this

enum Animal
{
    Cat,
    Dog,
    Cow,
    Pigeon
}

And class

public class Cow
{ }

public class Dog
{ }

public class Cow
{ }

public class Pigeon
{ }

That's what I want to achieve is to dynamically create a class object based on the selected enumu. Enum and class names are always the same. Enum and classes are dozens, so I do not want to add another case for each pair.

e.q.

public object GetAnimal(Animal animal)

used like GetAnimal(Animal.Cow); should return new Cow class object.

like image 353
Bogusz Michałowski Avatar asked Sep 03 '14 09:09

Bogusz Michałowski


Video Answer


2 Answers

    public object GetAnimal(Animal animal)
    {
        var ns = typeof(Animal).Namespace; //or your classes namespace if different
        var typeName = ns + "." + animal.ToString();

        return Activator.CreateInstance(Type.GetType(typeName));
    }
like image 101
MatteoSp Avatar answered Nov 15 '22 03:11

MatteoSp


An alternative is to use custom attributes and extension methods, to add the syntactic equivalent tof a method to the Enum. The accpeted answer is far simpler and therefore probably better, but you may find this of interest.

using System;
using System.Reflection;

namespace CustomAttributes
{
    [AttributeUsage(AttributeTargets.Field)]
    public class ConstructableEnumAttribute : Attribute
    {
        public Type Type { get; set; }

        public ConstructableEnumAttribute(Type type)
        {
            this.Type = type;
        }
    }

    public static class AnimalExtension
    {
        // This is your main mapping method.  It doesn't need to be an extension
        // method, so you could get the 'Construct(Animal.Cat)' syntax you requested,
        // but I like the ability to do:
        //     Animal myPet = Animal.Cat;
        //     object animal = myPet.Construct();
        public static object Construct(this Animal ofAnimal)
        {
            object animal = null;
            Type typeOfAnimal = GetType(ofAnimal);
            if ((null != typeOfAnimal) &&
                (!typeOfAnimal.IsAbstract))
            {
                animal = Activator.CreateInstance(typeOfAnimal);
            }
            return animal;
        }

        private static Type GetType(Animal animal)
        {
            ConstructableEnumAttribute attr = (ConstructableEnumAttribute)
                Attribute.GetCustomAttribute
                (ForValue(animal), typeof(ConstructableEnumAttribute));
            return attr.Type;
        }

        private static MemberInfo ForValue(Animal animal)
        {
            return typeof(Animal).GetField(Enum.GetName(typeof(Animal), animal));
        }
    }

    public enum Animal
    {
        [ConstructableEnum(typeof(Cat))]
        Cat,
        [ConstructableEnum(typeof(Dog))]
        Dog,
        [ConstructableEnum(typeof(Cow))]
        Cow,
        [ConstructableEnum(typeof(Pigeon))]
        Pigeon
    }

    public class Cat
    { }

    public class Dog
    { }

    public class Cow
    { }

    public class Pigeon
    { }

    public class Owner
    {
        Animal pet;
        Owner(Animal animal)
        {
            pet = animal;
        }

        public void ShowPet()
        {
            object theCreature = pet.Construct();
            Console.WriteLine("My pet is a " + theCreature.GetType().ToString());
        }
    }
}
like image 25
Evil Dog Pie Avatar answered Nov 15 '22 04:11

Evil Dog Pie