I have a factory class and I'd like it to be able to return an object of random type. The type should be chosen from a predefined list of types. So, something like:
public class NeutralFactory : NPCFactory
{
private List<Type> humanoids = new List<Type> { typeof(Dwarf), typeof(Fairy), typeof(Elf), typeof(Troll), typeof(Orc) };
private Random random = new Random();
public Creature CreateHumanoid(int hp = 100)
{
int index = random.Next(humanoids.Count);
return new humanoids[index]();
}
}
Sadly, this does not work.
I want to be able to pass arguments to the constructors, we can assume that they all have the same signature.
The only working way to do it I found is to use a switch statement and return a different object in each case:
public Creature CreateHumanoid(int hp = 100)
{
int index = random.Next(humanoids.Count);
switch (index)
{
case 0:
return new Dwarf(hp);
case 2:
return new Fairy(hp);
case 3:
return new Elf(hp);
case 4:
return new Troll(hp);
case 5:
return new Orc(hp);
default:
throw new Exception("This should not execute.");
}
}
I don't really like it though. Is there a better way to do it?
EDIT:
Here's what I ended up using:
private List<Func<int, string, Creature>> humanoids = new List<Func<int, string, Creature>> {
(hp, name) => new Fairy(hp, name),
(hp, name) => new Troll(hp, name),
};
private List<Func<int, Creature>> animals = new List<Func<int, Creature>> {
(hp) => new Wolf(hp)
};
public override Creature CreateHumanoid(int hp = 100, string name = null)
{
int index = random.Next(humanoids.Count);
return humanoids[index](hp, name);
}
public override Creature CreateAnimal(int hp = 100)
{
int index = random.Next(animals.Count);
return animals[index](hp);
}
I have found similar questions where () => function() syntax was used, but I did not understand it, I guess those are some kind of ad-hoc delegates?
Anyways, it works as I wanted and is pretty concise.
Here's a helpful MSDN page on the Func<int, Creature> thing for any future readers:
https://docs.microsoft.com/en-us/dotnet/api/system.func-2?view=netframework-4.8