Better way to create objects from strings

  • I'm looking for a better way to create objects based off of a value of a string.



    Consider the following:



    Input file:



    //each Vehicle type has a list of different options
    //whose length varies, I provided a simple case
    van*2006*dodge*grand caravan*green~
    car*2010*toyota*corolla*red~
    truck*2005*toyota*tundra*black~


    Classes:



    abstract class Vehicle: IVehicle{
    public int Year;
    public string Make;
    public string Model;

    ...
    }

    class Van : Vehicle
    {
    ...
    }

    class Car : Vehicle
    {
    ...
    }

    class Truck : Vehicle
    {
    ...
    }


    Program:



    static void Main(string[] args)
    {
    char delimiter = '*';
    string fileToRead = "inventory.csv";
    string currentLine = string.Empty;
    List<IVehicle> inventory = new List<IVehicle>();

    //Open file
    using (StreamReader reader = new StreamReader(fileToRead))
    {
    //while you read each line
    while ((currentLine = reader.ReadLine()) != null)
    {
    IVehicle temp;

    //Tokenize the line
    string[] parts = currentLine.Split(delimiter);

    switch(parts[0])
    {
    case "van":
    temp = new Van();
    ...
    break;
    case "car"
    temp = new Car();
    ...
    break;
    case "truck"
    temp = new Truck();
    ...
    break;
    }

    inventory.add(temp);
    }
    }

    ...
    }


    My problem with the code is the switch statement. It feels messy and I'm looking for a better way.


    What's a `Vechicle`?

    have you considered Enum.Parse?

  • ultimA

    ultimA Correct answer

    10 years ago

    In .Net laguages you can easily instatiate any object given only the full name of the class (=namespace+class name).



    Here is a runnable example:



    using System;
    using System.Reflection;

    namespace Test
    {

    class MsgPrinter
    {
    public MsgPrinter()
    {
    System.Console.WriteLine("Hello!");
    }
    }

    class Program
    {
    static void Main(string[] args)
    {
    Assembly assembly = Assembly.GetExecutingAssembly();
    MsgPrinter printer = assembly.CreateInstance("Test.MsgPrinter") as MsgPrinter;
    Console.Read();
    }
    }
    }


    So in your case it would break down to something like (of course, the names in your parameter file would need to exactly match the class names in your application):



    ...
    string[] parts = currentLine.Split(delimiter);
    Vehicle vehicle = Assembly.GetExecutingAssembly().CreateInstance(namespace_name+"."+parts[0]) as Vehicle;
    ...

    (First-time visitor to this site) I used this as an opportunity to learn about a feature - reflection - that I'd had absolutely no experience with. I don't know what the protocol here is, so rather than add my code to your answer I put it on http://steven.vorefamily.net/using-reflection-to-read-a-text-file/ - if I should add it to @ultimA's answer instead, or if this is otherwise inappropriate, please let me know.

License under CC-BY-SA with attribution


Content dated before 7/24/2021 11:53 AM

Tags used