Answered by:
Reflection with Inheritance

Question
-
I am trying to figure out how to dynamically load a class that inherits another class. For example, the parent class is:
internal abstract class Car { }
and the child classes are:
internal class Ford : Car { }
internal class Chevy : Car { }
internal class Jeep : Car { }
Now, let's say that I have a List of cars, like this:
private List<Car> cars;
and I wanted to add specific makes of cars to that list. I realize that I can statically load the makes of cars, like this:
cars.Add( new Ford( ) );
cars.Add( new Chevy( ) );
cars.Add( new Jeep( ) );
However, is there any way that I can have an array of strings, like this:
public String[] carsNames = { "Ford", "Chevy", "Jeep" };
and dynamically load the corresponding Ford, Chevy, and Jeep classes into the cars List, based on the carsNames array? If there are any good articles or tutorials, please provide the links to them!
Friday, April 20, 2012 4:50 PM
Answers
-
What makes a Ford car different from a Chevy car?
Those differences need to be expressed dynamically in the data (properties) of the class and not from difference of a class objects. The class should allow for a commonality of data storage and processing and not require a class be created based on a name or type.
I believe that the situations needs to be rexamined as to what the atomic base class really is...continuing with the car example, I would change the base class to be a vehicle, then the derived classes from that are car, then truck, followed by a bicycle. Each of the deriveds share a properties such as Name property, then number of wheels...etc.
William Wegerson (www.OmegaCoder.Com)
- Edited by OmegaManModerator Friday, April 20, 2012 8:16 PM
- Proposed as answer by servy42 Monday, April 23, 2012 1:57 PM
- Marked as answer by Bob ShenModerator Monday, May 7, 2012 3:16 AM
Friday, April 20, 2012 8:14 PMModerator
All replies
-
Hi,
You can use Activator.CreateInstance to create object from type or classname
or
by using Assembly.CreateInstance
for your case you can have something like,
Array.ForEach(carsNames, f=> cars.Add((Car)Assembly.GetExecutingAssembly().CreateInstance(f)));
read here about reflection.
I hope this helps you...
If this post answers your question, please click "Mark As Answer". If this post is helpful please click "Mark as Helpful".
Friday, April 20, 2012 5:03 PM -
Kriss, this is all ok, I have tried your code, but the indexes in List<T> are created, but all null.
Lets say he hasa class like:
abstract class Car { public abstract string Name { get; set; } public abstract void ShowName(); }
and this is an example of Ford class:
class Ford : Car { private string carname; public Ford(string car) { this.carname = car; } public override string Name { get { return carname; } set { this.carname = value; } } public override void ShowName() { Console.WriteLine("Ford`s name is {0}.", this.Name); } }
How you you pass values of string array to each of the class and actually instanitate the class?
Mitja
- Edited by Mitja Bonca Friday, April 20, 2012 5:36 PM
Friday, April 20, 2012 5:35 PM -
@Mitja, in the OP's example all of the classes have default constructors, unlike your example. In the OPs code the array contains the class's name (unfortunately not fully qualified, so that'll be a part of the problem), not the parameter to initialize it with.Friday, April 20, 2012 5:42 PM
-
I can see that, but I was just wondering if he/I/you will do it like its my example?
I know its of topic, but still curious how to work it out.
Mitja
Friday, April 20, 2012 5:48 PM -
You can probably come up with ways to do this using reflection. There are a few other actual answers to your question, but instead, I'd suggest you find another way to do this. Reflection should be a last resort, not something to make typing easier. You can solve this without using reflection by introducing a factory pattern. To meet your requirements, I'd do something like this instead:
public static class CarFactory { public static Car CreateCar(string type) { if (type.Equals("Ford")) return new Ford(); else if (type.Equals("Chevy")) return new Chevy(); else if (type.Equals("Jeep")) return new Jeep(); } } public List<Car> ConvertStringArrayToCars(IEnumerable<string> carTypes) { return carTypes.Select(x => CarCreateCar(x)).ToList(); }
Check out My Blog. Now updated to actually work!
Friday, April 20, 2012 7:04 PM -
What makes a Ford car different from a Chevy car?
Those differences need to be expressed dynamically in the data (properties) of the class and not from difference of a class objects. The class should allow for a commonality of data storage and processing and not require a class be created based on a name or type.
I believe that the situations needs to be rexamined as to what the atomic base class really is...continuing with the car example, I would change the base class to be a vehicle, then the derived classes from that are car, then truck, followed by a bicycle. Each of the deriveds share a properties such as Name property, then number of wheels...etc.
William Wegerson (www.OmegaCoder.Com)
- Edited by OmegaManModerator Friday, April 20, 2012 8:16 PM
- Proposed as answer by servy42 Monday, April 23, 2012 1:57 PM
- Marked as answer by Bob ShenModerator Monday, May 7, 2012 3:16 AM
Friday, April 20, 2012 8:14 PMModerator