Reputation: 831
I am a C# beginner. I hope you have patience with me. Lets say I have an enum
public enum Dogs
{
Terrier,
Poodle,
Pitbull,
}
and some dog classes
public class Terrier {
}
public class Poodle {
}
public class Pitbull {
}
And I for some reason want to instantiate each of the classes dynamically from their types (enum values),
foreach(Dogs d in Enum.GetValues(typeof(Dogs)))
{
// d myDog = new d();
// "...is a variable but is used like a type"
}
I have also tried with
var myDog = Activator.CreateInstance(d);
// "...cannot convert from namespace.Dogs to System.Type"
Upvotes: 0
Views: 427
Reputation: 5629
Don't use an enum for that. A much saner solution is an array of Types:
private static Type[] dogs =
{
typeof(Terrier),
typeof(Poodle),
typeof(Pitbull),
}
Then you can still go over them all:
foreach (Type type in dogs)
{
Object dog = Activator.CreateInstance(type);
}
Though unless you're only using .ToString()
on it, you might want to give those classes a common interface or superclass to inherit (as rfmodulator also said in his answer) so you can actually call functions on the resulting objects. If all three inherit from a Dog
superclass, which makes them share a common Bark()
method, you can at least do something like this:
public abstract class Dog
{
String Bark();
}
public class Terrier : Dog
{
public override String Bark() { return "Woof!"; }
}
public class Poodle : Dog
{
public override String Bark() { return "Yap"; }
}
public class Pitbull : Dog
{
public override String Bark() { return "Whuff!"; }
}
...so you can actually get something useful out of your instantiated objects:
foreach (Type type in dogs)
{
Dog dog = (Dog)Activator.CreateInstance(type);
Console.WriteLine(dog.Bark());
}
The only slight downside to this method, from a design perspective, is that there's no way to enforce that only sub-types of Dog
can be put in the Type[] dogs
array; technically, any type object can be put in there. So that's the programmer's responsibility to not mess that up.
Upvotes: 2
Reputation: 1580
If you really want it:
(typeof(Dogs)).Assembly.CreateInstance(d.ToString());
Upvotes: 4
Reputation: 3738
Dogs.Terrier
is a different thing than Terrier
.
Here is how you could do something like you're describing:
For simplicity, I'm going to make all the classes implement a common interface, IDog:
public interface IDog { }
public class Terrier : IDog
{
}
public class Poodle : IDog
{
}
public class Pitbull : IDog
{
}
Now we can do this:
IDog dog;
foreach (Dogs d in Enum.GetValues(typeof(Dogs)))
{
switch (d)
{
case Dogs.Terrier:
dog = new Terrier();
break;
case Dogs.Poodle:
dog = new Poodle();
break;
case Dogs.Pitbull:
dog = new Pitbull();
break;
default:
throw new Exception("no such dog!");
}
Debug.WriteLine($"dog is {dog.GetType()}");
}
Upvotes: 1