简体   繁体   中英

Get column Lists from non-generic IEnumerable using Reflection

I have a method which takes a generic IEnumerable and generates lists of unique values for each column. Needless to say this is very slow, I'm guessing it's due to all the reflection used. Here's some sample code:

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);
            }
        }
    }

Can I generate a list of values for each property without going through the IEnumerable row by row and casting each property as an object?

Is there a faster way to do something like this for each item in IEnumerable?:

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

}

One possible problem here is you are passing a non-generic collection which could be differents objects, so, create the propertyInfo should be inside the loop to make sure you can read that property from the object. If you are sure that all the objects inside the non-generic collection are the same type, you could read the propertyInfo outside the loop from the first object on the list (if it has at least one instance).

You could try this, see the comments on the code:

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;
}

See the working sample with differnt objects on the collections: https://dotnetfiddle.net/bPgk4h

The issue had nothing to do with the IEnumerable or reflection. Data hadn't been populated in the IEnumerable, so it was making thousands of database calls I was populating the matrix. After fixing that issue, it loads in no time.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM