0

I would like to iterate through a list of classes that extend class "A" and create objects of the extended classes' type.

Is there a way to replace the className in "new className();" with a variable or do I have to use a switch statement to create objects of different types?

List <A> listOfSubClasses; //A list of classes that all extend "A"
List <A> objects; //List to hold created objects
int[] variable; 
foreach (A subClass in listOfSubClasses){
    for (int i = 0; i < 3; i++){ //Let's say I want to create 3 objects of every class
        objects.Add (new subClass()); //This is the line my question refers to
        objects[objects.Count - 1].someParameter = variable[i];
    }
}
user4676310
  • 383
  • 1
  • 3
  • 12

2 Answers2

1

You can use a List<Type> to store the types you want to instanciate, and then, use System.Activator.CreateInstance to create the instances from the type

using System;
using System.Collections.Generic;

public class A
{
    public int someParameter;
}
public class B : A {}
public class C : A {}
public class D : A {}

public class Program
{
    public static void Main()
    {
        List <Type> listOfSubClasses = new List<Type>
        {
            typeof(B),
            typeof(C),
            typeof(D)
        };
        List <A> objects = new List<A>();

        int[] variable = { 1, 2, 3 }; 
        foreach (var subClass in listOfSubClasses) {
            for (int i = 0; i < 3; i++) {
                objects.Add((A)Activator.CreateInstance(subClass));
                objects[objects.Count - 1].someParameter = variable[i];
            }
        }
    }
}
Cid
  • 14,968
  • 4
  • 30
  • 45
  • I will freely admit that i am an insufferable nitpicker (sometimes), but _someProperty_ here is actually a field, not a property. I just found that funny... okay, okay, i'll take my coat and leave... ;-) –  Jun 14 '19 at 12:50
  • @elgonzo I noticed that few minutes ago, but I was too lazy to modify that. Feel free to edit :) – Cid Jun 14 '19 at 12:51
  • 1
    I happily oblige and vandalized your answer ;) –  Jun 14 '19 at 12:52
0

You can use reflection for that. (I haven't checked this solution on my machine, so there may be minor differences.)

using System;

// ...

List<Type> listOfSubClasses =
    from assembly in AppDomain.CurrentDomain.GetAssemblies()
    from type in assembly.GetTypes()
    where type.IsSubclassOf(typeof(A))
    select type;

List<A> objects;
int[] variable; 
foreach (Type subClass in listOfSubClasses) {
    for (int i = 0; i < 3; i++) {
        objects.Add((A)Activator.CreateInstance(subClass));
        objects[objects.Count - 1].someParameter = variable[i];
    }
}

Activator.CreateInstance uses the default constructor to create an object, but there are other overloads if you need something else.

The solution for providing all subclasses of a class is here.

Tolik Pylypchuk
  • 680
  • 1
  • 6
  • 15