tsxp
tsxp

Reputation: 13

Instantiate an unknown at compile time child of an abstract class

EDIT

See Amir Popovich's solution for answer and a follow up question (how to pass CTOR params)

Here's the inner loop of my final code:

//The names of my children classes are the gpib name from *?IDN
//Some start with numbers, thus removing the _ character
if (child.Name.Replace("_","") == gpibInstrument)
{
    var instance = (GpibDevice)Activator.CreateInstance(child, gpibAddr);
    gpibDeviceList.add(instance);
    break;
}

ORIGINAL

I'm trying to figure out how to instantiate an unknown at compile time child class of an abstract class based on some set of logic. The logic is as follows:

  1. Get connected equipment
  2. Instantiate classes based off of the equipment I see
  3. Return a list of those classes

The main reason I'm doing this is so I don't have to come back to this code and add the different child classes as I add more child classes.

Here's the code I have so far:

//Get IEnumerable of available children class types of my abstract
//class GpibDevice
var children = typeof(GpibDevice)
               .Assembly.GetTypes()
               .Where(t => t.IsSubclassOf(typeof(GpibDevice)) && !t.IsAbstract);

//Get list of connected equipment
string[] equipList = GpibUtilites.GetEquipmentNames();

//List which will contain the newly instantiated classes
List<GpibDevice> gpibDeviceList = new List<GpibDevice>();

foreach (var gpibInstrument in equipList)
{
    foreach (var child in children)
    {
        if(child.Identifier == gpibInstrument)
        {
            //////INSTATIATE HERE//////
            gpibDeviceList.add(instantiatedClass);
        }
    }
}
return gpibDeviceList;

Thanks!

Upvotes: 1

Views: 87

Answers (1)

Amir Popovich
Amir Popovich

Reputation: 29836

Use Activator.CreateInstance and cast to your abstract class:

if(child.Identifier == gpibInstrument)
{
    //////INSTATIATE HERE//////
    var instance = (AbstractClassType)Activator.CreateInstance(child);
    gpibDeviceList.add(instantiatedClass);
}

If you know you class has parameters in it's CTOR, you can pass then as an object[]:

var @params = new object[]{p1,p2...pn};
var instance = (AbstractClassType)Activator.CreateInstance(child, @params);

Upvotes: 1

Related Questions