Динамическое создание типа для коллекции - 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);
}
}
}