C#List to DataTable扩展方法未检索属性

C#List to DataTable扩展方法未检索属性,c#,.net,generics,reflection,extension-methods,C#,.net,Generics,Reflection,Extension Methods,我想将knomolijst类型的ObservableCollection转换为DataTable。我找到了它的扩展方法,但它没有检索我的属性 扩展方法: public static class ListToDataTable { public static DataTable ToDataTable<T>(this IList<T> items) { DataTable dataTable = new Dat

我想将knomolijst类型的ObservableCollection转换为DataTable。我找到了它的扩展方法,但它没有检索我的属性

扩展方法:

public static class ListToDataTable
    {
        public static DataTable ToDataTable<T>(this IList<T> items)
        {
            DataTable dataTable = new DataTable(typeof(T).Name);

            //Get all the properties
            PropertyInfo[] Props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);

            foreach (PropertyInfo prop in Props)
            {
                //Defining type of data column gives proper data table 
                var type = (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>) ? Nullable.GetUnderlyingType(prop.PropertyType) : prop.PropertyType);
                //Setting column names as Property names
                dataTable.Columns.Add(prop.Name, type);
            }
            foreach (T item in items)
            {
                var values = new object[Props.Length];
                for (int i = 0; i < Props.Length; i++)
                {
                    //inserting property values to datatable rows
                    values[i] = Props[i].GetValue(item, null);
                }
                dataTable.Rows.Add(values);
            }
            //put a breakpoint here and check datatable
            return dataTable;
        }
    }
这是它接收到的knomolijst类型:

   public class KNMOLijst
        {
            public string VoorLetters { get; set; }

            public string Voornaam { get; set; }

            public string TussenVoegsel { get; set; }

            public string Achternaam { get; set; }

            public string Geslacht { get; set; }

            public DateTime GeboorteDatum { get; set; }

            public string InstrumentNaam { get; set; }

            public KNMOLijst()
            {

            }
        }
我确保这些财产是公开的

这是扩展方法接收的列表

generatedList.Add(new KNMOLijst()
                {
                    VoorLetters = (string)(row["VoorLetters"]),
                    Voornaam = (string)(row["Voornaam"]),
                    TussenVoegsel = (string)(row["TussenVoegsel"]),
                    Achternaam = (string)row["Achternaam"],
                    Geslacht = (string)row["Geslacht"],
                    GeboorteDatum = (DateTime)row["GeboorteDatum"],
                    InstrumentNaam = (string)row["InstrumentNaam"]
                });
调用ToDataTable方法的我的viewmodel

public class SecretarisViewModel : BaseViewModel
    {
        private readonly SecretarisBLL secretarisBll;

        private ObservableCollection<object> generatedList;

        public ObservableCollection<object> GeneratedList
        {
            get { return generatedList; }
            set
            {
                generatedList = value;
                NotifyPropertyChanged();
            }
        }

        private DataTable generatiedDataTable;

        public DataTable GeneratedDataTable
        {
            get => generatiedDataTable;
            set
            {
                generatiedDataTable = value;
                NotifyPropertyChanged();
            }
        }

        public SecretarisViewModel()
        {
            secretarisBll = new SecretarisBLL();
            GeneratedList = new ObservableCollection<object>();
            generatiedDataTable = new DataTable();
        }

        public async Task GetKNMOList()
        {
            var dataset = await secretarisBll.GetKNMOList();

            foreach (DataRow row in dataset.Tables[0].Rows)
            {
                generatedList.Add(new KNMOLijst()
                {
                    VoorLetters = (string)(row["VoorLetters"]),
                    Voornaam = (string)(row["Voornaam"]),
                    TussenVoegsel = (string)(row["TussenVoegsel"]),
                    Achternaam = (string)row["Achternaam"],
                    Geslacht = (string)row["Geslacht"],
                    GeboorteDatum = (DateTime)row["GeboorteDatum"],
                    InstrumentNaam = (string)row["InstrumentNaam"]
                });
            }

            GeneratedDataTable = generatedList.ToDataTable();
        }
    }
公共类SecretarisViewModel:BaseViewModel
{
私有只读SecretarisBLL SecretarisBLL;
私有可观察集合生成列表;
公共可观测集合生成列表
{
获取{return generatedList;}
设置
{
生成列表=值;
NotifyPropertyChanged();
}
}
私有数据表GeneratedDataTable;
公共数据表GeneratedDataTable
{
get=>generatiedDataTable;
设置
{
GeneratedDataable=值;
NotifyPropertyChanged();
}
}
公共秘书视图模型()
{
secretarisBll=新secretarisBll();
GeneratedList=新的ObservableCollection();
GenerateedDataTable=新数据表();
}
公共异步任务getknomolist()
{
var dataset=await secretarisBll.getknomlist();
foreach(数据集中的DataRow行。表[0]。行)
{
Add(新的knomolijst()
{
VoorLetters=(字符串)(第[“VoorLetters”]行),
Voornaam=(字符串)(行[“Voornaam”]),
TussenVoegsel=(字符串)(第[“TussenVoegsel”]行),
Achternaam=(字符串)行[“Achternaam”],
Geslacht=(字符串)行[“Geslacht”],
Geboortedatam=(日期时间)行[“Geboortedatam”],
InstrumentNaam=(字符串)行[“InstrumentNaam”]
});
}
GeneratedDataTable=generatedList.ToDataTable();
}
}
为什么它无法获取列表的属性

生成的列表是一个可观察的集合, 所以我假设如果我在其中添加一个新的knomolijst行,它会 是Knomolijst类型的吗

否,如果列表的类型为
observateCollection
,则
T
System.Object
,它没有公共属性。因此,将其设置为一个
可观察的集合

如果无法执行此操作,请修改方法以从第一项派生类型:

public static DataTable ToDataTable<T>(this IList<T> items)
{
    Type type = items.FirstOrDefault()?.GetType();
    if (type == null)
        throw new InvalidOperationException("The properties are derived from the first item, so the list must not be empty");

    DataTable dataTable = new DataTable(type.Name);
    //Get all the properties
    PropertyInfo[] Props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);

    // ...
}
公共静态数据表到数据表(此IList项)
{
类型类型=items.FirstOrDefault()?.GetType();
if(type==null)
抛出新的InvalidOperationException(“属性派生自第一项,因此列表不能为空”);
DataTable=新的DataTable(type.Name);
//获取所有属性
PropertyInfo[]Props=type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
// ...
}

顺便说一下,这种行为(在空列表上抛出
invalidooperationexception
)与执行相同操作的行为类似。它还需要使用反射来获取列。

什么是
T
——生成列表的类型是什么?如果它不是实现IList的东西,那么它不会起作用。到目前为止,您尝试了什么?列表的类型正确吗?代码对我有效。通过你的样本检查,有效。因此,我猜您的
不包含这些值。您可以在调用ToDataTable方法的位置添加代码吗?@JeroenMostert生成的列表是一个ObservableCollection,因此我假设如果我将一个新的knomolijst行添加到其中,它将属于knomolijst类型?我尝试了这一点,但在调试过程中跳过了类型检查。这是类型到达该行时包含的内容:{Name=“knomolijst”FullName=“Gildenbondsharmonie.BO.Lists.knomolijst”}。但它仍然没有收到我的属性?@Brum:跳过了哪种类型检查?该部分:type type type=items.FirstOrDefault()?.GetType();如果(type==null)type=typeof(T);但是我将包括项目中内容的屏幕截图。@Brum:我已经用您的示例检查了该方法,并声明它为
observetecollection
。在我更改之前,它不工作,因为
System.Object
被用作类型,现在它工作了。你是我的人,是我的英雄!我没有注意到你有过一次机会,当我修改代码时,它起了作用。谢谢你的时间,我真的很感激!
public static DataTable ToDataTable<T>(this IList<T> items)
{
    Type type = items.FirstOrDefault()?.GetType();
    if (type == null)
        throw new InvalidOperationException("The properties are derived from the first item, so the list must not be empty");

    DataTable dataTable = new DataTable(type.Name);
    //Get all the properties
    PropertyInfo[] Props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);

    // ...
}