Search code examples
c#dictionaryinterfaceinitialization

Instantiating a class based on a string value or grouping a set of classes without using an Interface


I have some code which receives a string - depending on that string is which class is instantiated e.g. if its "customer" it does new CustomerData() etc. There will be 10-30 different string values and each has an associated class that would need instantiating:

I did think of using a dictionary to resolve this:

  public IData data; //the classes are currently in an interface but this is looking impractical due to differing methods.

  data = dataLookup["dataType"];

  dataLookup = new Dictionary<string, **what data type is this?**>
        {
            { "customer", new CustomerData() },
            { "company", new CompanyData() }
            ...etc 10-30 rows... 
        };

The problem is i dont know how to set the datatype in the dictionary - i dont think adding all the classes to an interface is the answer. Although the classes are all related (they are all "data" for the application), only about half the methods in each data class are the same, the rest of the methods are unique to each data class. I've read on Interfaces that i could just add the unused methods in each class and no-op them, but it does sound a bit messy.

What would be the cleanest solution to instantiate the correct class based on the string value?


Solution

  • Since all of you classes have parameterless constructors (according to comments), as an option you can manage a dictionary of string as a key and Type as value (instead of concrete instance).

    var dict = new Dictionary<string, Type>()
    {
        { "customer", typeof(CustomerData) },
        { "company", typeof(CompanyData) },
    };
    

    And use it in the following way, get a type by key from a dictionary and create an instance of that type. But this instance has an Object type, since you can't use a type known at runtime during a compile time. The possible way here is use Convert.ChangeType and store the result in dynamic type variable

    var type = dict["customer"];
    var data = Activator.CreateInstance(type);
    dynamic result = Convert.ChangeType(data, type);