Лучший способ для создания объектов из строки


Я ищу лучший способ создать объекты на основе значения строки.

Рассмотрим следующие:

Входной файл:

//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~

Классы:

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

    ...
}

class Van : Vehicle
{
    ...
}

class Car : Vehicle
{
    ...
}

class Truck : Vehicle
{
    ...
}

Программа:

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);
        }
    }

    ...
}

Моя проблема с кода оператора switch. Он чувствует себя грязным, и я ищу лучший способ.



43661
7
c#
задан 17 августа 2011 в 03:08 Источник Поделиться
Комментарии
3 ответа

В .Чистая переводы вы можете легко создания экземпляров любого объекта дается только полное имя класса (=пространство имен+имя класса).

Вот работоспособный пример:

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();
}
}
}

Так что в вашем случае было бы сломать что-то подобное (конечно, имена в файле параметров должны совпадать с именами классов в приложении):

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

10
ответ дан 17 августа 2011 в 05:08 Источник Поделиться

Вот несколько советов:


  1. Я хотел бы использовать регулярное выражение (и в частности групп регулярных выражений) для разбора строк.

  2. Вместо огромной переключатель/заявление случае лучше использовать небольшой класс IDictionary, который содержит все возможные сопоставления от типа автомобиля конструктора:

        IDictionary<string, Func<IVehicle>> carBuilder = new Dictionary<string, Func<IVehicle>>();
    carBuilder.Add("van", () => { return new Van(); });
    carBuilder.Add("car", () => { return new Car(); });
    carBuilder.Add("truck", () => { return new Truck(); });

И вы всегда можете получить экземпляр типа с использованием транспортного средства:

IVehicle vehicle = carBuilder["van"]();

Это всегда лучше, чтобы четко отделить проблемы:


  • Ввести класс ДТО называется VehicleInfo, который будет содержать все столбцы строки в CSV-файл.

  • Ввести класс для парсинга CSV-файл с именем VehicleInfoProvider, у которого есть метод:

    общественного объекта IList GetVehicleInfos(строка путь)


Он будет парсить файл с помощью регулярных выражений и заполнить все поля класса VehicleInfo


  • Другой класс, который можно создать средствами на основе VehicleInfo. Позволяет назвать его VehicleBuilder. У него есть метод:

    CreateVehicle публичных IVehicle(VehicleInfo информация)


Этот класс будет содержать словарь и сможете создавать все возможные виды транспортных средств.


  • С помощью оператора foreach можно парсить строки файла и создания всех экземпляров:

        IList<VehicleInfo> vehicleInfos = vehicleProvider.GetVehicleInfos(path);

    foreach (var vehicleInfo in vehicleInfos)
    {
    IVehicle vehicle = vehicleBuilder.CreateVehicle(vehicleInfo.VehicleType);
    inventory.Add(vehicle);
    }


6
ответ дан 20 августа 2011 в 07:08 Источник Поделиться

Вы могли бы использовать абстрактный узор завод и передать тип транспортного средства, чтобы создать метод фабрики. Что, несомненно, будет чище и позволяют легче exstensibility, когда кто-то хочет создать новый тип автомобиля (кроссовер, внедорожник и т. д.).

Пример может быть найден здесь.

3
ответ дан 17 августа 2011 в 04:08 Источник Поделиться