The cleanest way to create a class from an enum type?

I have the following enumerations and classes:

public enum MyEnum
{
   MyType1,
   MyType2
}

public abstract class MyBaseClass
{
   public abstract MyEnum GetMyType();
}

public class MySubClass : MyBaseClass
{
   public override MyEnum GetMyType()
   {
      return MyEnum.MyType1;
   }
}

I want to create an instance of MySubClass based on GetMyType (), but without the need to "register" MySubClass for some kind of handler (or is this the way?). I know that this is probably easy to do with reflection (loop through the assembly for classes that inherit from MyBaseClass and check their MyType), but is this a way?

I'm doing something long right now:

public MyBaseClass CreateMyClass(MyEnum myEnum)
{
   if(myEnum == MyEnum.MyType1)
   {
      return new MySubClass();
   }
   else if(myEnum == MyEnum.MyType2)
   {
      return new MyOtherSubClass();
   }
}

Ultimately, this will cause me to forget to manually add new classes. It will be caught in the test, but I would prefer not to add classes at all, since all the necessary information has already been provided.

Open to everyone suggestions for the best approach.

+4
source
2

enum.

public class MyCustomAttribute : Attribute
{
    public MyEnum EnumType { get; set; }
}

;

public enum MyEnum
{
    MyType1,
    MyType2
}
public class MyBaseClass
{

}
[MyCustomAttribute(EnumType = MyEnum.MyType1)]
public class MySubClass : MyBaseClass
{

}
[MyCustomAttribute(EnumType = MyEnum.MyType2)]
public class MyOtherClass : MyBaseClass
{

}

Reflection .

private static Dictionary<MyEnum, Type> _myEnumDictionary = new Dictionary<MyEnum, Type>();

public MyBaseClass GetEnumClass(MyEnum enumType)
{
    if (!_myEnumDictionary.ContainsKey(enumType))
    {
        var enumClass = typeof(MySubClass).Assembly
            .GetTypes()
            .FirstOrDefault(x => x.GetCustomAttributes<MyCustomAttribute>()
                .Any(k => k.EnumType == enumType));
        if (enumClass == null)
        {
            throw new Exception("There is no declared class with the enumType" + enumType);
        }
        _myEnumDictionary.Add(enumType, enumClass);
    }
    return (MyBaseClass)Activator.CreateInstance(_myEnumDictionary[enumType]);
}

, :

var mySubClass = GetEnumClass(MyEnum.MyType1);
var myOtherClass = GetEnumClass(MyEnum.MyType2);
//There is no lookup here. It will get the Type from Dictionary directly.
var mySubClass2 = GetEnumClass(MyEnum.MyType1); 

, Dictionary<MyEnum, Type> .

+4

, .

public enum MyEnum
{
    Type1, Type2
}
public abstract class MyBaseClass
{
    public abstract MyEnum GetMyType();
}
public class MySubClass1 : MyBaseClass
{
    public override MyEnum GetMyType()
    {
        // implementation
    }
}
public class MySubClass2 : MyBaseClass
{
    public override MyEnum GetMyType()
    {
        // implementation
    }
}

, MySubClass1 MySubClass2 MyBaseClass.
.

    public MyBaseClass CreateMyClass(MyEnum myEnum)
    {
        var dict = new Dictionary<MyEnum, Type>();
        dict.Add(MyEnum.Type1, typeof(MySubClass1));
        dict.Add(MyEnum.Type2, typeof(MySubClass2));

        var type = dict.Where(x => x.Key == myEnum).Select(x => x.Value);
        var instance = Activator.CreateInstance(type.GetType());
        return (MyBaseClass)instance;
    }

. Dictionary Enum Type.
Enum , Activator , .

- - , MyBaseClass dict, .

--------------- EDIT ----------------

, string ,

ObjectType instance = 
 (ObjectType)Activator.CreateInstance("MyAssembly","MyNamespace." + argType);
+1

Source: https://habr.com/ru/post/1692909/


All Articles