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

How can I resolve the Class type for generic parameter, when the parameter value is being passed as an interface?

考虑具有以下签名的方法:

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 只包含接口属性而不包含与 class在列表中,继承自接口。

明确地说,我的界面和我的 class 定义是 public,我的 class 中的属性也是如此。

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

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

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