开发者

How can I find the type of T in a c# Generic collection of T when all I know is the type of the collection?

开发者 https://www.devze.com 2023-04-01 19:41 出处:网络
I have an array of PropertyInfo representing the properties in a class. Some of these properties are of type ICollection<T>, but T varies across the properties - I have some ICollection<strin

I have an array of PropertyInfo representing the properties in a class. Some of these properties are of type ICollection<T>, but T varies across the properties - I have some ICollection<string>, some ICollection<int>, etc.

I can easily identify which of the properties are of type ICollection<> by using the GetGenericTypeDefinition() method on type, but I am finding it impossible to get the type of T - the int or string in my example above.

Is there a way开发者_StackOverflow to do this?

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
    }
}


If you know it'll be ICollection<X> but don't know X, that's fairly easy with 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...
    }
}

It gets harder when the type is some type which implements ICollection<T> but may itself be generic. It sounds like you're in a better position :)


I believe this is what you are looking for:

typeOfProperty.GetGenericArguments()[0];

That will return you the T part of a generic List<T> for example.


Jon's solution will yield T. Depending on the context, you might need to access the getter return type instead in order to get int, string, etc. For example...

// 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());
}
0

精彩评论

暂无评论...
验证码 换一张
取 消