当我所知道的是集合的类型时,如何在C#的通用集合中找到T的类型?

时间:2011-09-02 12:27:19

标签: c# .net generics

我有一个PropertyInfo数组,表示类中的属性。其中一些属性属于ICollection<T>类型,但T在属性中各不相同 - 我有一些ICollection<string>,一些ICollection<int>等。

我可以通过在类型上使用GetGenericTypeDefinition()方法轻松识别哪些属性类型为ICollection<>,但我发现无法获取T的类型 - 上面示例中的int或字符串

有办法做到这一点吗?

IDocument item
PropertyInfo[] documentProperties = item.GetType().GetProperties();    
PropertyInfo property = documentProperties.First();
Type typeOfProperty = property.PropertyType;

if (typeOfProperty.IsGenericType)
{
    Type typeOfProperty = property.PropertyType.GetGenericTypeDefinition();

    if (typeOfProperty == typeof(ICollection<>)
    {
        // find out the type of T of the ICollection<T>
        // and act accordingly
    }
}

3 个答案:

答案 0 :(得分:8)

如果您知道它会ICollection<X>但不知道X,那么使用GetGenericArguments相当容易:

if (typeOfProperty.IsGenericype)
{
    Type genericDefinition = typeOfProperty.GetGenericTypeDefinition();

    if (genericDefinition == typeof(ICollection<>)
    {
        // Note that we're calling GetGenericArguments on typeOfProperty,
        // not genericDefinition.
        Type typeArgument = typeOfProperty.GetGenericArguments()[0];
        // typeArgument is now the type you want...
    }
}

当类型是实现 ICollection<T>的某种类型时,它会变得更难,但它本身可能是通用的。听起来你处于更好的位置:)

答案 1 :(得分:4)

我相信这就是你要找的东西:

typeOfProperty.GetGenericArguments()[0];

这将返回通用List&lt; T&gt;的T部分。例如。

答案 2 :(得分:1)

Jon的解决方案将产生T.根据上下文,您可能需要访问getter返回类型,以获取int,string等。例如......

// The following example will output "T"
typeOfProperty = property.PropertyType.GetGenericTypeDefinition();
Type genericDefinition = typeOfProperty.GetGenericTypeDefinition();
if (genericDefinition == typeof(ICollection<>))
{
    Type t1 = typeOfProperty.GetGenericArguments()[0];
    Console.WriteLine(t1.ToString());
}

// Instead you might need to do something like the following...
// This example will output the declared type (e.g., "Int32", "String", etc...)
typeOfProperty = property.GetGetMethod().ReturnType;
if (typeOfProperty.IsGenericType)
{
    Type t2 = typeOfProperty.GetGenericArguments()[0];
    Console.WriteLine(t2.ToString());
}