【问题标题】:Get column Lists from non-generic IEnumerable using Reflection使用反射从非通用 IEnumerable 获取列列表
【发布时间】:2019-05-09 20:20:36
【问题描述】:

我有一个方法,它采用通用 IEnumerable 并为每列生成唯一值列表。不用说这很慢,我猜这是由于使用了所有反射。 下面是一些示例代码:

private void PopulateReferenceMatrices(IEnumerable newValue)
    {
        Type t = newValue.GetType();
        Type baseType = t.GetGenericArguments()[0];
        PropertyInfo[] properties;
        Dictionary<string, int> indexValues = new Dictionary<string, int>();
        properties = baseType.GetProperties();
        int numProperties = properties.Count(); 
        ListValues = new List<object>[numProperties];
        for (int i = 0; i < numProperties; i++)
        {
            indexValues.Add(properties[i].Name, i);
            FilterValues[i] = new List<object>();
        }
        //populate values into array
        foreach (dynamic da in newValue)
        {
            foreach (PropertyInfo d in properties)
            {
                Object property = d.GetValue(da);
                ListValues[indexValues[d.Name]].Add(property);
            }
        }
    }

我可以为每个属性生成一个值列表,而无需逐行遍历 IEnumerable 并将每个属性转换为对象吗?

是否有更快的方法来为 IEnumerable 中的每个项目执行类似的操作?:

public IList getRowValue(IEnumerable value, string propertyName)
{
    value.Select(x => x.propertyName).ToList();

}

【问题讨论】:

  • 你用反射做什么,你一般想完成什么?
  • 这是一个自定义的datagrid控件,每个headerColumn中都有一个列表框来过滤网格中的数据。 ListValues 是在这些列表框中选中或取消选中的值。由于我无法知道在运行时传递到自定义数据网格中的类型,因此我必须即时弄清楚。
  • 你为什么使用dynamic daGetProperty 是什么?为什么你循环 PropertyInfo 对象只是为了将 d.Name 传递给方法?
  • 我认为动态可能会加快速度(文档说它把大多数东西都当作对象对待)。我认为可能有一种方法可以更轻松地从动态引用中获取属性。 GetProperty 是对 CompilerServices.Versioned.CallByName 函数的调用,因为有人写过它更快。不是(我把它改回GetValue(da)。关于属性,第一次主要是创建一个字典来快速访问一个索引,另外一次我多次使用它。
  • a 是干什么用的?获取整数的顺序列表似乎是一种非常复杂的方法,就像通过字典查找来获取整数一样。 for (int j1 = 0; j1 &lt; numProperties; ++j1) ListValues[j1].Add(properties[j1].GetValue(da));(还有int numProperties = properties.Length;)呢?另外,为什么这不是IEnumerable&lt;T&gt; 的通用方法?

标签: c# list ienumerable


【解决方案1】:

这里一个可能的问题是您传递了一个可能是不同对象的非泛型集合,因此,创建 propertyInfo 应该在循环内以确保您可以从对象中读取该属性。如果您确定非泛型集合中的所有对象都是同一类型,则可以从列表中的第一个对象(如果它至少有一个实例)读取循环外的 propertyInfo。

你可以试试这个,看看代码上的 cmets:

public static IList GetRowValue(IEnumerable value, string propertyName)
{
    // create an arraylist to be the result
    var result = new ArrayList();

    // loop in the objects
    foreach (var item in value)
    {
        // search for a property on the type of the object
        var property = item.GetType().GetProperty(propertyName);

        // if the property was found
        if (property != null)
        {
            // read the property value from the item
            var propertyValue = property.GetValue(item, null);

            // add on the result
            result.Add(propertyValue);
        }
    }

    return result;
}

查看集合中不同对象的工作示例:https://dotnetfiddle.net/bPgk4h

【讨论】:

  • 鉴于baseType 的定义方式,它是一个通用的IEnumerable&lt;&gt;,由于某种原因以IEnumerable 的形式传入。
【解决方案2】:

该问题与 IEnumerable 或反射无关。 数据尚未填充到 IEnumerable 中,因此它进行了数千次数据库调用,我正在填充矩阵。 修复该问题后,它会立即加载。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-04
    • 2012-11-12
    • 2012-05-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多