将IEnumerable<T>转换为object[,] C#

3
我正在尝试构建一个通用的方法,将任何IEnumerable转换为object[,]。这样做的目的是通过ExcelDNA插入到Excel中,最好使用2d object数组。
我对反射不熟悉,需要一些严肃的帮助来填补这方面的空白。下面发布的代码是我目前拥有的内容,我需要获得外部循环中DataSource中索引i处T的属性。在内部循环中,然后依次获取每个属性的值并插入object[,]。
任何帮助都将受到赞赏。 谢谢 理查德
    public object[,] ConvertListToObject<T>(IEnumerable<T> DataSource)
    {
        int rows = DataSource.Count();

        //Get array of properties of the type T
        PropertyInfo[] propertyInfos;
        propertyInfos = typeof(T).GetProperties(BindingFlags.Public);

        int cols = propertyInfos.Count();   //Cols for array is the number of public properties

        //Create object array with rows/cols
        object[,] excelarray = new object[rows, cols];

        for (int i = 0; i < rows; i++) //Outer loop
        {
            for(int j = 0; j < cols; j++) //Inner loop
            {
                object[i,j] =             //Need to insert each property val into j index
            }
        }
        return excelarray;
       }
}
3个回答

5

你已经很接近了,以下是一些指针:

  • 外部循环需要是foreach循环,因为通常情况下不能通过索引高效访问IEnumerable
  • GetProperties需要BindingFlags.Static.Instance才能返回任何内容。
  • 通过调用propertyInfos[j].GetValue获取实际值,传入要从中获取它的T-实例和一个索引器值的数组 - 对于常规属性为null,但如果你的对象可能具有索引属性,则需要找出要在此处传递的内容或处理可能抛出的异常。

我得到的结果大致如下:

public object[,] ConvertListToObject<T>(IEnumerable<T> DataSource)
{
    int rows = DataSource.Count();
    //Get array of properties of the type T
    PropertyInfo[] propertyInfos;
    propertyInfos = typeof(T).GetProperties(
        BindingFlags.Public |
        BindingFlags.Instance); // or .Static
    int cols = propertyInfos.Length;
    //Create object array with rows/cols
    object[,] excelarray = new object[rows, cols];
    int i = 0;
    foreach (T data in DataSource) //Outer loop
    {
        for (int j = 0; j < cols; j++) //Inner loop
        {
            excelarray[i, j] = propertyInfos[j].GetValue(data, null);
        }
        i++;
    }
    return excelarray;
}

GetValue 的文档说明对于非索引属性,第二个参数应该为 null。这将减轻垃圾收集器的负担。 - phoog
好的,我也从你的答案中借鉴了几个修复方法 :-) - phoog
还有一个我提到但没有放入我的代码中的修复,现在我已经修复了。 - Rawling

1

由于您无法对可枚举对象进行索引,因此应在 foreach 循环中枚举它并同时递增计数器,而不是使用 for 循环。

int i = 0;
foreach (var row in DataSource)
{
    for (int j = 0; j < cols; j++)
        excelarray[i,j] = propertyInfos[j].GetValue(row, null);
    i++;
}

1
    public object[,] ConvertListToObject<T>(IEnumerable<T> dataSource)
    {
        if (dataSource != null)
        {
            var rows = dataSource.Count();
            var propertyInfos = typeof (T).GetProperties(BindingFlags.Public);
            var cols = propertyInfos.Length;
            var excelarray = new object[rows,cols];
            var i = 0;
            foreach (var data in dataSource)
            {
                for (var j = 0; j < cols; j++)
                {
                    excelarray[i, j] = propertyInfos[j].GetValue(data, null);
                }
                i++;
            }
            return excelarray;
        }
        return new object[,] {};
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接