Перебор общего типизированного списка в c#

#c# #generic-programming #generic-list

#c# #общее программирование #общий список

Вопрос:

Я пытаюсь выполнить итерацию по списку объектов общего типа, я могу получить свойства объекта, однако не могу получить значения из свойств каждого экземпляра объекта. Вот как выглядит мой код: я хочу создать функцию, которая преобразует любой переданный ей список и преобразует его в DataTable.

—DataObject

 public class StudentDo
{
     public int Id {get;set}
     public string Name {get;set}
}
 

—Общий объект доступа к данным

 public DataTable ConvertListToDataTable(List<T> list, string tableName = "")
{
     var type = typeof(T);
     var properties = type.GetProperties().ToList();
     DataTable dt = new DataTable(tableName);
     properties.ForEach(x =>
     {
         dt.Columns.Add(x.Name);
     });

     // i don't know how shall i pull data from each instance of List<T>.
     return dt;
}
 

Комментарии:

1. Похоже, это не проблема с итерацией по общему списку. Ваш вопрос, похоже, касается того, как считывать значения свойств с помощью отражения.

2. Просто любопытно, почему вы хотите преобразовать коллекцию хорошо структурированных типов в DataTable ? В большинстве случаев все, что вы хотите сделать, DataTable вы можете сделать с помощью List<T>

Ответ №1:

Перебор списка и вставка в каждый столбец с использованием отражения —

 public static DataTable ConvertListToDataTable<T>(List<T> list, string tableName = "")
        {
            var type = typeof(T);
            var properties = type.GetProperties().ToList();
            DataTable dt = new DataTable(tableName);
            properties.ForEach(x =>
            {
                dt.Columns.Add(x.Name);
            });
            foreach (var item in list)
            {
                var dataRow = dt.NewRow();
                properties.ForEach(x =>
                {
                    dataRow[x.Name] = x.GetValue(item, null);
                });
                dt.Rows.Add(dataRow);
            }
            return dt;
        }
 

Комментарии:

1. Это работает нормально, если идти дальше, есть ли способ включить только те свойства для класса, у которого есть значения, и избежать остальных свойств при создании datatable.

2. @Abbas, ты имеешь в виду пропустить нулевые значения?

3. Я имею в виду пропустить загрузку свойств в datatable, который содержит нулевые или пустые значения

Ответ №2:

Это то, что я использую:

     public DataTable ToDataTable<T>(IList<T> data)
    {
        PropertyDescriptorCollection properties =
            TypeDescriptor.GetProperties(typeof(T));
        DataTable table = new DataTable();
        foreach (PropertyDescriptor prop in properties)
            table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
        foreach (T item in data)
        {
            DataRow row = table.NewRow();
            foreach (PropertyDescriptor prop in properties)
                row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
            table.Rows.Add(row);
        }
        return table;
    }