I'm not starting with an object and trying to determine it's type. I'm starting with parameters and trying to decide which animal type to instantiate as.
Really? Your question really doesn't convey this.
At any rate, let's give it a go.
Given a string parameter, we may want to create either a Cat
or a Dog
. Let's write a function which does that:
public Animal CreateAnimal(string parameter)
{
if(parameter == "cat")
return new Cat();
else
return new Dog();
}
var strings = new[]{ "cat", "cat", "dog" };
var animals = strings.Select(s => CreateAnimal(s)).ToList();
This seems all well and good, but what happens if we don't know what Cat
and Dog
are at compile time? Well, at some point we have to have a dictionary which maps parameters to actual types. We can look in this dictionary to find the type, then create an instance of it.
The code would look a bit like this:
public static Dictionary<string, Type> lookup = {
{ "cat", typeof(Cat) },
{ "dog", typeof(Dog) },
{ "fish", typeof(Fish) }, // people can add things to lookup dynamically
}
public Animal CreateAnimal(string parameter)
{
var animalType = lookup[parameter];
return (Animal)Activator.CreateInstance(animalType);
}
This will work, but there are 2 problems.
Activator.CreateInstance
is not the fastest thing in the world. Generally it's fine but if you're creating 100,000 animals you'll notice
- More importantly, because we are just storing types and doing casts to
Animal
, the compiler can't check anything for us. We could put typeof(Ferrari)
in the dictionary and it would all compile fine, but it would crash when the app was run.
The next step is to use generics. Instead of storing the Type
in the dictionary, we can store a lambda function which does the work of creating the animal. That way, we can use generics, and the compiler can fully check that all the animals are legit.
public static Dictionary<string, Func<Animal>> lookup = {
{ "cat", () => new Cat() },
{ "dog", () => new Dog() },
{ "fish", () => new Fish() }, // people can add things to lookup dynamically
}
public Animal CreateAnimal(string parameter)
{
var creatorFunc = lookup[parameter];
return creatorFunc(); // call the lambda which does the creating
}
Hope this helps!