I have a certain amount of classes which inherit from an abstract class:
abstract public class baseClass
{
//logics
}
public class child1 : baseClass
{
}
public class child2 : baseClass
{
}
now I've got some management class which will have to create one of these classes depending on a enum which will have as value the same name so like this:
public enum ClassType
{
child1,
child2
}
public class Manager
{
private List<baseClass> _workers;
public void Initialize(ClassType type)
{
//what logics to put here? (resulting in correctChild)
_workers.Add(correctChild);
}
}
I was thinking of typeof but don't know quite how to implement it.
Note: in this example it's 2 classes but in the real case it's an arbitrary amount of classes.
If you don't need the overhead of attributes and you are running this from the same assembly - you can just use the executing assembly to load the type via reflection. Activator.CreateInstance
can take care of building the object for you dynamically.
public class Manager
{
private List<baseClass> _workers = new List<baseClass>();
public void Initialize(ClassType type)
{
string assemblyName = Assembly.GetExecutingAssembly().GetName().Name;
Type objType = Type.GetType(string.Format("{0}.{1},{0}", assemblyName, type.ToString()));
var correctChild = (baseClass)Activator.CreateInstance(objType);
_workers.Add(correctChild);
}
}
Have a look at Activator.CreateInstance()
Creates an instance of the type whose name is specified, using the named assembly and default constructor.
so the code would look something like
Activator.CreateInstance(type.ToString(),assemblyName);
I'm actually familiar with such an implementation, i've used it myself.
I would also recommend looking into this article that explains how you can actually use attributes on the enum values, to store the actual class names. You can even use it as an extension.
public static string Description(this Enum enumValue) {
Type enumType = enumValue.GetType();
FieldInfo field = enumType.GetField(enumValue.ToString());
object[] attributes = field.GetCustomAttributes(typeof(DescriptionAttribute), false);
return attributes.Length == 0 ? enumValue.ToString() : ((DescriptionAttribute)attributes[0]).Description;
}
The code will then look something like
Activator.CreateInstance(classType.Description(), assemblyName);
There are many way to differentiate between types.
you can use the is
operator
var o = ...;
if (o is Child1) {}
or you could use the as
operator
var child = o as Child1;
if (child != null) {}
or what you described yourself already, the typeof
operator.
What I am sensing though, is that if you have a strong need for type casting, there might be something else at hand. Maybe you can solve your problem by Polymorphism. Then you don't have to distinguish between all the different types in lengthy if-else
or case-switch
constructions, but you can delegate the 'different behavior' to your subclasses.
If you dont want to use if statements, can you use case statements? like:
public class Manager
{
private List<baseClass> _workers;
public void Initialize(ClassType type)
{
switch (type)
{
case child1:
_workers.Add(correctChild);
break;
case child2:
_workers.Add(correctChild);
break;
}
}
}