Как использовать отражение для сериализации и десериализации (общий способ).Не используя dll - PullRequest
0 голосов
/ 16 мая 2018

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

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

Идея состоит в том, что я использую метод CsvSerialise, а вход - это byteArray, и преобразую его в список объектов, где на входе указан тип вывода, который я хочу.

Если у кого-то есть идеи, пожалуйста, дайте им.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
using System.Text.RegularExpressions;

namespace DocumentArchiveV2.Util
{
    public class CsvSerialiser
    {
        public List<Output> CsvSerialise<Output, DestinationFormat>(byte[] csvData, Type destinationType)
        {
            try
            {
                List<List<string>> lislistCsvData = BinaryDataToList(csvData);
                List<string> columnNames = lislistCsvData[0];
                List< destinationType >  = new List<DestinationFormat>();


                // loop over de regels / records
                for (int i = 1; i < lislistCsvData.Count - 1; i++)
                {

                    var Instance = Activator.CreateInstance(destinationType);
                    var properties = Instance.GetType().GetProperties();

                    foreach (var property in properties)
                    {
                        int index = columnNames.FindIndex(x => x == property.Name);
                        if (index >= 0)
                        {
                            PropertyInfo propertyInfo = destinationType.GetProperty(lislistCsvData[i][index]);
                            Type propertyType = propertyInfo.GetType();
                            var geconverteerdeWaarde = VindPropertyNaam(propertyType, lislistCsvData[i][index]);
                            propertyInfo.SetValue(propertyInfo, geconverteerdeWaarde);
                        }
                    }
                }
            }
            catch (Exception)
            {
                throw;
            }
        }

        public object VindPropertyNaam(Type type, string popertyName)
        {
            try
            {
                var parse = type.GetMethod("Parse", new[] { typeof(string) });
                if (parse == null) throw new NotSupportedException();
                return parse.Invoke(null, new object[] { popertyName });
            }
            //or don't catch
            catch (Exception)
            {
                return null;
            }
        }


        private object LoadRecord(Type propertyType)
        {
            throw new NotImplementedException();
        }

        private List<List<string>> BinaryDataToList(byte[] csvData)
        {
            try
            {
                List<List<string>> serialised = new List<List<string>>();

                foreach (var line in Regex.Split(Encoding.ASCII.GetString(csvData), "\r\n"))
                {
                    string[] splittedLine = line.Split(';');
                    serialised.Add(line.Split(';').ToList());
                }
                return serialised;
            }
            catch (Exception ex)
            {
                DiagnoseLib.Logging.Logger.Error(ex.Message);
                return null;
            }
        }
    }
}

Ответы [ 2 ]

0 голосов
/ 16 мая 2018

Я нашел, где я пошел не так.

Я пытался вернуть универсальный тип, в то время как это должен был быть тип объекта

Спасибо всем, кто дал понимание.

     public List<object> CsvSerialise(byte[] csvData, object destinationType)
            {
        // The rest of the code with some small adjustments
            }
0 голосов
/ 16 мая 2018

Мне очень не нравится ваш код из-за многочисленных нарушений правил ООП, которые, как известно, являются лучшими.Однако, поскольку это не тот вопрос, который вы задаете, я бы хотел игнорировать их и сосредоточиться на том, что вы хотели бы получить прямо сейчас.

Так что в основном то, что вы делаете, называется "анализом"».Все дело в том, чтобы взять как-то отформатированный (CSV в вашем случае) текст и преобразовать его во внутренние структуры данных.Поскольку вы стремитесь придумать общее решение (которое само по себе идеально, хотя и гораздо сложнее), вы объективно не знаете, какой будет структура данных.Следовательно, вы должны быть в состоянии настроить этот процесс.Как?Как правило, с помощью функций высшего порядка.Что-то вроде new DataStructureBuilder<TDataStructure>((environment, result) => result.Text = environemt["Text"]).Это далеко не настоящий код, но дает представление: есть общая структура данных (предполагающая) типа TDataStructure, и вы указываете, каким образом она должна быть явно заполнена данными.environment обозначает анализируемый текст (в тот самый момент, когда вы читаете значения, которые вы хотите, чтобы ваши структуры данных передавались дальше, однако они сохраняются в виде необработанных словарей, списков, хэш-наборов и т. Д.).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...