Динамическое создание типа для коллекции - C#
Формулировка задачи:
Здравствуйте!
Есть такая задумка, но не знаю как реализовать.
Файл электронной таблицы, в котором допустим есть 10 колонок, моя программа не знает о количестве и названиях колонок. Описание этой таблицы находится во внешнем файле, условно
Я могу жестко прописать тип моей структуры и использовать только нужные в данный момент поля. Но если состав электронной таблицы изменится, то мне придётся переписывать код, а хочется сделать универсальную программу, в которой структура
config.xml
. Хочу сделать либоStruct
, либоClass
, в которых буду описывать тип моей электронной таблицы(названия колонок). Допустим мне надо из 10 колонок только 5 использовать для работы. Какие именно колонки надо использовать я беру из файлаsettings.xml
вот ещё был мой вопрос и ещё моя темаusing System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Xml.Linq; using ExcelLibrary; using DocumentFormat.OpenXml.Packaging; namespace XML_Parser { struct DataArray { public string Type_1; public string Type_2; public string Type_3; public string Type_4; public string Type_5; public string Type_6; public string Type_7; public string Type_8; public string Type_9; public string Type_10; public DataArray(string type_1, string type_2, string type_3, string type_4, string type_5, string type_6, string type_7, string type_8, string type_9, string type_10) { Type_1 = type_1; Type_2 = type_2; Type_3 = type_3; Type_4 = type_4; Type_5 = type_5; Type_6 = type_6; Type_7 = type_7; Type_8 = type_8; Type_9 = type_9; Type_10 = type_10; } class ConvertSelectetdFile { List<DataArray> workList = new List<DataArray>(); ........................некий код, который работает с этой коллекцией.......................... }
DataArray
создавалась бы на основе файла настроек и ещё лучше, если только нужные поля электронной таблицы считывать и записывать значения в поля динамически созданнойDataArray
. В общем как можно создать типизированную коллекциюList<DataArray>
, в которой тип получается и создаётся из файла настроек. Программа не знает ничего, а только использует файла настроек. Спасибо!Решение задачи: «Динамическое создание типа для коллекции»
textual
Листинг программы
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace XML_Parser { /// <summary> /// Класс для загрузки и работы с параметрами файлов. /// Здесь можно будет выбирать какие колонки необходимо /// обрабатывать, а какие нужно скрыть /// </summary> [Serializable] public class Column { public string Parameter { get; set; } public string value { get; set; } public Column() { } public Column(string _param, string _value) { Parameter = _param; value = _value; } } } using System; using System.Collections.Generic; using System.ComponentModel; using System.Text; using System.Data; using System.IO; using System.Xml.Linq; using Excel; namespace XML_Parser { /// <summary> /// Класс, в котором будет проводится чтение заданного файла с учётом параметров(заданных колонок) /// </summary> class ReadSelectedFile { private Dictionary<string, Sele_2> _dictionary; //создание делегата метода принимающего путь к файлу, отдельный поток выполнения и файл настроек нужных колонок private delegate List<Column[]> Sele_2(string path, System.ComponentModel.BackgroundWorker worker, List<Column> preset); //контейнер в котором будем хранить данные из загруженного файла электронной таблицы с учётом нужных колонок private List<Column[]> result = new List<Column[]>(); public ReadSelectedFile() { _dictionary = new Dictionary<string, Sele_2> { {".xls", pars_xls}, {".xlsx", pars_xlsx}, {".xml", pars_xml }, }; } private List<Column[]> pars_xml(string path, BackgroundWorker worker, List<Column> preset) { XNamespace o = "urn:schemas-microsoft-com:office:office"; XNamespace x = "urn:schemas-microsoft-com:office:excel"; XNamespace ss = "urn:schemas-microsoft-com:office:spreadsheet"; XDocument xDoc; try { xDoc = XDocument.Load(path); } catch (Exception exp) { throw; } //список заголовков колонок, значения которых надо использовать List<string> tempNameColumn = new List<string>(); foreach (var item in xDoc.Descendants(ss + "Row").ElementAt(0).Elements()) { //проводим сравнение название колонки со списком настроек, нужно ли использовать колонку или нет if (Convert.ToBoolian(item.Find((xx) => xx==(preset.Preset).value)) { tempNameColumn.Add(item.Value); } } //создаем массив колонок для одной строки в списке List<Column[]> Column[] tempColumn = new Column[tempNameColumn.Count]; foreach (XElement item in xDoc.Descendants(ss + "Row")) { int i = 0; foreach (var item_2 in item.Elements()) { tempColumn[i] = new Column(); tempColumn[i].Parameter = tempNameColumn[i]; tempColumn[i].value = item_2.Value; i++; } result.Add(tempColumn); } result.RemoveAt(0); return result; } private List<Column[]> pars_xlsx(string path, BackgroundWorker worker, List<Column> preset) { ........... } private List<Column[]> pars_xls(string path, BackgroundWorker worker, List<Column> preset) { ................ } internal List<Column[]> Read(string path, BackgroundWorker backgroundWorker, List<Column> list) { return _dictionary[Path.GetExtension(path)](path, backgroundWorker, list); } } }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д