Обобщите метод для работы с различными объектами - PullRequest
0 голосов
/ 14 июля 2011

В программе, которую я пишу, я решил использовать свои собственные типы данных вместо любой другой базы данных (в образовательных целях).

Данные сохраняются в виде файлов CSV, и у меня естьметод для преобразования из .csv в простую строку [,].

Каждый класс X как отдельная строка [,] для преобразования списка.После первых 3 классов я начал играть с дженериками и рефлексией.Мне удалось преобразовать общий список в строку [,], но теперь все выглядит иначе.

способ, которым я реализую список в строку [,]:

public string[,] ToArray(object[] sender)
    {
        if (sender.Length==0)
        {

            return null;
        }
        string[,] ret; 
        PropertyInfo[] props;
        if (sender.Length > 0)
        {
            props = sender[0].GetType().GetProperties();
            ret = new string[props.Length, sender.Length];
        }
        else
        {

            return null;
        }
        for (int i=0;i<sender.Length;i++)
        {



            for (int p = 0; p < props.Length; p++)
            {
                object value=props[p].GetValue(sender[i], null);
               if (value!=null) ret[p, i] = value.ToString();

            }


        }
        return ret;


    }

и, скажем, класс Windows (имя строки, двойной размер, bool Blinds)

Я конвертирую массив [,] в Windows (в общем) вот так:

public static List<Windows> ToList(string[,] arra)
    {

        List<Windows> ret = new List<Windows>(); // change Windows to anything
        int col = array.GetLength(1);
        int row = array.GetLength(0);

        PropertyInfo[] props=PropArray(new Windows());
        int propslen=props.Length;
        for (int c = 0; c < col; c++)
        {
            Windows entry=new Windows();
            for (int r = 0; r < propslen; r++)
            {
                Type pt = props[r].PropertyType;

                if (pt==typeof(string))
                    props[r].SetValue(entry,array[r,c],null);
                else
                    if (pt==typeof(int))
                    {
                        int i=0;int.TryParse(array[r,c],out i);
                    props[r].SetValue(entry,i,null);
                    }
                else
                    if (pt==typeof(bool))
                    {
                        bool i = false; bool.TryParse(array[r, c], out i);
                    props[r].SetValue(entry,i,null);
                    }
                    else
                        if (pt == typeof(double))
                        {
                            double i = 0; double.TryParse(array[r, c], out i);
                            props[r].SetValue(entry, i, null);
                        }
                    else
                if (pt==typeof(DateTime))
                    {
                        DateTime i = DateTime.MinValue; DateTime.TryParse(array[r, c], out i);
                    props[r].SetValue(entry,i,null);
                    }





            }
            ret.Add(entry);


            }

        return ret;


        }

Все, что мне нужносделать, это найти, заменить слово «Windows» на любой другой тип данных, и это работает.

Реальный вопрос в том, как я могу обобщить его, чтобы получить тип и составить список экземпляров все это самостоятельно?

Это вообще возможно?

Заранее спасибо, Габриэль

Ответы [ 2 ]

0 голосов
/ 14 июля 2011

То, что вы делаете, по сути является форматом сериализации. Форматы сериализации относительно просты, если объекты являются значениями без сложных ссылок. Простой XML или JSON являются распространенными форматами. Возможно, вам стоит заняться использованием json?

Если вы идете по принципу «катите сами», почему бы не попробовать использовать имена свойств в качестве ключей? Добавьте в список ключей / значений имя класса и создайте экземпляры объектов при десериализации. Пример формата

MyApplication.Person, MyAssembly
Name=Steve
Age=30
MyApplication.Person, MyAssembly
Name=Bob
Age=54

Чтобы десериализовать, прочитайте имя класса, установите с помощью FormatterServices.GetUninitializedObject (), чтобы получить пустой экземпляр класса. Затем, используя информацию о свойствах этого класса, установите значения из пар ключ / значение, которые следуют в файле. По сути, это упрощенная нотация JSON (не поддерживает списки, карты и т. Д.)

0 голосов
/ 14 июля 2011

Я не буду безошибочным, но вы можете использовать дженерики. Что-то вроде:

public static List<T> ToList<T>(string[,] arra) // T can be anything
    where T : new()                             // as long as it has a default constructor
{

    List<T> ret = new List<T>();
    int col = array.GetLength(1);
    int row = array.GetLength(0);

    PropertyInfo[] props=PropArray(new T());
    int propslen=props.Length;
    for (int c = 0; c < col; c++)
    {
        T entry=new T();
// ...
...