Given an enum type:
public enum Work
{
Normal,
Extended
}
What I would like to do is the following.
public abstract class Builder<T>
{
public static Builder<T> GetBuilder<T> (T work)
{
return new Builder<T> ();
}
}
public class BuilderNormal : Builder<Work.Normal>
{
}
public class BuilderExtended : Builder<Work.Extended>
{
}
I specifically want to avoid using a switch/case in Builder or using a mapping that I would need to maintain when I would add a new enum value to Work, i.e. I could do this
public abstract class Builder
{
public static Builder GetBuilder (Work work)
{
switch (work)
{
case Work.Normal:
return new BuilderNormal ();
case Work.Extended:
return new BuilderExtended ();
default:
throw new ...
}
}
}
So, basically, I want to create an instance of a class depending on an enum value and the class must be a child class of an abstract class.
You can’t in the way you’ve designed, basically. Generic type parameters are always for types, not values.
What you can certainly do is maintain a single
Dictionary<Work, Func<Builder>>to allow you to basically register factories. That will avoid the switch statement, but it’s still somewhere that you could forget to add values.I’d rely on unit tests to avoid the problem though – write a test which checks that you can create a
Builderfor every value within the enum; then if you ever add a value to the enum without adding a mapping, your test will fail.EDIT: Another option would be to add an attribute to the enum values to say which builder type corresponds to that value. You’d then need to extract that type with reflection and instantiate it that way.