c# - 如何使用反射在 IEnumerable<T> 上调用 System.Linq.Enumerable.Count<>?

标签 c# generics reflection collections ienumerable

我有一堆 IEnumerable 集合,它们的确切数量和类型经常更改(由于自动代码生成)。

看起来像这样:

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

在运行时,我想确定每个类型并计算它,而不必在每次代码生成后重写代码。所以我正在寻找一种使用反射的通用方法。我正在寻找的结果是这样的:

MyType: 23
OtherType: 42

我的问题是我不知道如何正确调用 Count 方法。这是我到目前为止所拥有的:

        // 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 method (this fails)
                    object count = localCountMethodInfo.Invoke(collection, null);

                    System.Diagnostics.Debug.WriteLine("{0}: {1}", genericArgument.Name, count);
                }
            }
        }

最佳答案

如果你坚持用艰难的方式去做;p

变化:

  • 如何获取通用方法的 countMethodInfo
  • Invoke 的参数

代码(注意 obj 是我的 MyCollections 实例):

    MethodInfo countMethodInfo = typeof (System.Linq.Enumerable).GetMethods().Single(
        method => method.Name == "Count" && method.IsStatic && method.GetParameters().Length == 1);

    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(obj, 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 method (this fails)
                object count = localCountMethodInfo.Invoke(null, new object[] {collection});

                System.Diagnostics.Debug.WriteLine("{0}: {1}", genericArgument.Name, count);
            }
        }
    }

关于c# - 如何使用反射在 IEnumerable<T> 上调用 System.Linq.Enumerable.Count<>?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3546051/

相关文章:

c# - NSubstitute 为对象返回 Null

Java泛型分配全局变量

java - 为实现 Comparable 的泛型类创建一个 compareTo

java - java反射的问题

c# - 在静默模式下安装 SQL Server Express 2008 以及 C# 应用程序

c# - 如何使用 Open XML 和 C# 更改单个段落或页面的方向?

c# - Action(() => { }) 通过调度程序卡住用户界面

swift - 为什么泛型类型不通过调用链下游的约束参与方法重载?

java - scala重写静态java方法

c# - 如何检索属性关联对象的实例?