I have the following enum 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" the MySubClass to some kind of handler (or is that the way to go?). I know this is probably easy to do via reflection (loop through Assembly for classes which inherit from MyBaseClass and check their MyType), but is that the way to go?
Right now I'm doing something a long the lines:
public MyBaseClass CreateMyClass(MyEnum myEnum)
{
if(myEnum == MyEnum.MyType1)
{
return new MySubClass();
}
else if(myEnum == MyEnum.MyType2)
{
return new MyOtherSubClass();
}
}
Which eventually will result in me forgetting to manually add new classes. It will be caught in a Test, but I'd rather not having to add classes at all since all the information needed is already provided.
Open to all kind of suggestions regarding the best approach.
You could create a custom attribute to identify desired enum class.
public class MyCustomAttribute : Attribute
{
public MyEnum EnumType { get; set; }
}
Then the enum and the classes;
public enum MyEnum
{
MyType1,
MyType2
}
public class MyBaseClass
{
}
[MyCustomAttribute(EnumType = MyEnum.MyType1)]
public class MySubClass : MyBaseClass
{
}
[MyCustomAttribute(EnumType = MyEnum.MyType2)]
public class MyOtherClass : MyBaseClass
{
}
You could use Reflection
to determine the related class with enum.
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]);
}
Finally, you can get instance of the related class like that;
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);
Also, you can use a static Dictionary<MyEnum, Type>
dictionary collection to prevent lookup everytime.