Alex Rivera | Logout

How to invoke System.Linq.Enumerable.Count<> on IEnumerable<T> using Reflection?

Asked 2010-08-23T09:01:52.553
9

I have a bunch of IEnumerable Collections which exact number and types is subject of frequent changes (due to automatic code generation).

It looks something like this:

public class MyCollections {
    public System.Collections.Generic.IEnumerable<SomeType> SomeTypeCollection;
    public System.Collections.Generic.IEnumerable<OtherType> OtherTypeCollection;
    ...

At runtime i want to determine each Type and it's count without having to rewrite the code after every code generation. So i am looking for a generic approach using reflection. The result i am looking for is something like:

MyType: 23
OtherType: 42

My problem is that i can't figure how to invoke the Count method properly. Here is what i have so far:

        // Handle to the Count method of System.Linq.Enumerable
        MethodInfo countMethodInfo = typeof(System.Linq.Enumerable).GetMethod("Count", new Type[] { typeof(IEnumerable<>) });

        PropertyInfo[] properties = typeof(MyCollections).GetProperties();
        foreach (PropertyInfo property in properties)
        {
            Type propertyType = property.PropertyType;
            if (propertyType.IsGenericType)
            {
                Type genericType = propertyType.GetGenericTypeDefinition();
                if (genericType == typeof(IEnumerable<>))
                {
                    // access the collection property
                    object collection = property.GetValue(someInstanceOfMyCollections, null);

                    // access the type of the generic collection
                    Type genericArgument = propertyType.GetGenericArguments()[0];

                    // make a generic method call for System.Linq.Enumerable.Count<> for the type of this collection
                    MethodInfo localCountMethodInfo = countMethodInfo.MakeGenericMethod(genericArgument);

                    // invoke Count meth
Edit
Report

1 Answer

1
var count = System.Linq.Enumerable.Count(theCollection);

Edit: you say it's generated though, so can you not just generate a properties with calls to Count()?

public class MyCollections
{
    public System.Collections.Generic.IEnumerable<SomeType> SomeTypeCollection;
    public System.Collections.Generic.IEnumerable<OtherType> OtherTypeCollection;

    public int CountSomeTypeCollection
    {
        get { return this.SomeTypeCollection.Count(); }
    }

    ...
answered 2010-08-23T09:08:55.977

Your Answer