0

Basically I have an abstract class with we'll say two properties, one being abstract and some derived classes.

public abstract class BaseClass { 
    public string ID { get; set; } 
    public abstract string Name { get; };
}

public class Class1 : BaseClass { // id would be 1
    public string Name { get { return "Class1 Name"; }
}

public class Class2 : BaseClass {
    public string Name { get { return "Class2 Name"; }
}

public class Class3 : BaseClass {
    public string Name { get { return "Class3 Name"; }
}

Then I have a method in my data layer that returns basically a list of ID's for the base class. What I'm asking is if I can create a new instance of the DerivedClass based on what these ID's are without if or switch statements? So...

List<BaseClass> list = new List<BaseClass>();
string id = dataReader["ID"].ToString(); // say this id = 1
list.Add(new BaseClass { ID = id }); // this would be "Class1 Name" and the Class would be Class1

I know I can't create a new instance of an abstract class so the 'new BaseClass()' doesn't work, but that's the only way I know how to explain it. I've looked into making a copy or clone with Reflection, but not sure if it's actually going to do what I want. This very well might not be possible, but figured I'd ask.

biggfu444
  • 61
  • 1
  • 5
  • 1
    Use a variant of the [factory method pattern](https://en.wikipedia.org/wiki/Factory_method_pattern). Create a static method (either in BaseClass or in a separate class serving as factory), whose purpose is to create and return an instance of a concrete type based on some parameter passed to the static method... –  Mar 12 '19 at 16:03
  • Thank you, this is what I'm looking for, instead of having logic wherever I create the class, just have it one place. However the implementation is what is tripping me up, I don't want to have to update the factory if a new derived class would be added in the future. – biggfu444 Mar 12 '19 at 16:39

2 Answers2

1

How about:

switch(id) {
   case "1": list.Add(new Class1());
   break;
   ...
}

You could also use:

list.Add((BaseClass)Activator.CreateInstance("AssemblyName", "Class"+id));

see also How do I instantiate a class given its string name?

Bart Friederichs
  • 33,050
  • 15
  • 95
  • 195
0

Create a dictionary that contains the types associated with their ids (which its value will be in the string property you will depend on):

Dictionary<string, Type> dictOfTypes = new Dictionary<string, Type>();
dictOfTypes.Add("1", typeof(Class1));

Then depending on the id you have you can get the item from the Dictionary and then create the instance:

string id = "1";
Type classType = dictOfTypes[id];
var instance = Activator.CreateInstance(classType);
Dabbas
  • 3,112
  • 7
  • 42
  • 75