You can do it with reflection if you really want, but there will be performance penalties. Whether they're significant or not will depend on your exact situation.
Depending on exactly what you want to do, I'd quite possibly go with either a switch/case statement or a map, as you suggest. In particular, that would be useful if you need to pass different arguments to different constructors based on the type you're constructing - doing that via reflection would be a bit of a pain in that you'd already be special-casing different types.
EDIT: Okay, so we now know that there will always be a parameterless constructor. In that case, your JSON could easily contain the class name without the namespace (if they're all in the same namespace) and your method could look something like this:
public FooParent CreateFoo(string name)
{
if (name == null)
{
throw new ArgumentNullException("name");
}
string fullName = "Some.NameSpace." + name;
// This is assuming that the type will be in the same assembly
// as the call. If that's not the case, we can look at that later.
Type type = Type.GetType(fullName);
if (type == null)
{
throw new ArgumentException("No such type: " + type);
}
if (!typeof(FooParent).IsAssignableFrom(type))
{
throw new ArgumentException("Type " + type +
" is not compatible with FooParent.");
}
return (FooParent) Activator.CreateInstance(type);
}
Where do you determine the name to use? If it's passed in somewhere, a switch statement can be very simple when reformatted away from the norm a little:
public FooParent CreateFoo(string name)
{
switch (name)
{
case "Foo1": return new Foo1();
case "Foo2": return new Foo2();
case "Foo3": return new Foo3();
case "Foo4": return new Foo4();
case "FooChild1": return new FooChild1();
default:
throw new ArgumentException("Unknown Foo class: " + name);
}
}
Mind you, having just written that out I'm not sure it has any real benefit (other than performance) over using Type.GetType(name)
and then Activator.CreateInstance(type)
.
How does the caller know the class name to pass in? Will that definitely be dynamic? Is there any chance you could use generics? The more you could tell us about the situation, the more helpful we could be.