当参数值作为接口传递时,如何解析泛型参数的类类型?

本文关键字:参数 泛型 何解析 类型 接口 | 更新日期: 2023-09-27 17:50:50

考虑一个签名如下的方法:

void foo(List<T> myList) ...

我们假设,通过反射,需要构造这样一个函数,并获得T类型参数的PropertyInfo细节。调用typeof(T).GetProperties(...)应该可以做到这一点,所以我们可以在我们的方法中添加以下行,以获得这些详细信息。

void foo(List<T> myList)
{
    PropertyInfo[] props = 
        typeof(T).GetProperties(BindingFlags.Public 
            | BindingFlags.Instance 
            | BindingFlags.FlattenHierarchy);
    ...
}

这提供了我们需要的信息…除了当T是一个接口参数时,我发现的是props只包含接口属性,而不是与列表中继承自接口的类相关的属性。

要清楚,我的接口和类定义是公共的,类中的属性也是公共的。

如何获得与继承接口的实际类型相关联的属性,而不是严格的接口属性?

当参数值作为接口传递时,如何解析泛型参数的类类型?

如果您想要实际的类型,您可能需要为每个项目获取它:

foreach (T t in myList)
{
    Type itemType = t.GetType();
    itemType.GetProperties(...)
    // etc.
}

您还可以为不同的类型添加特定的代码:

if(itemType == typeof(MyConcreteType))
{
    // do specific stuff for that type
}

如果您想获得List<T>中包含的所有对象属性的扁平列表,这里有一个LINQ解决方案:

IEnumerable<PropertyInfo> properties =
                          myList.SelectMany(x => x.GetType()
                                                  .GetProperties(BindingFlags.Public | 
                                                                 BindingFlags.Instance));

如果您需要访问声明类型,您可以查看PropertyInfo.DeclaryingType

如果你不想要一个扁平的列表,Select可以这样做:

IEnumerable<PropertyInfo[]> properties =
                            myList.Select(x => x.GetType()
                                                .GetProperties(BindingFlags.Public | 
                                                               BindingFlags.Instance));