Hoshi
Hoshi

Reputation: 607

What type is inside a generic container

public T getValueByName<T>(String name)
{
    if( T is List )
        Object containedType = T.WhatGoesHere()?
...

In the above code, I need to know if I can convert a List to whatever type of list is passed in, e.g., List<Control>.

Is there a way to interrogate the generic for the contained type? I could get List<Control>, List<String>, List<Form> etc..

I could split the API to return lists in a separate method where the contained type is passed in, thus requiring the caller to use one method for lists and one for simple types. Either way they have to know what's coming back, but if there's a smooth way to do what I'm asking about, I'd rather keep the API simple.

Note: this is a solution to the lack of covariance because even though there is an implicit conversion operator defined on the contained type, a cast of List to T fails. So, in order to follow the solution listOfB.Cast<A>(); from here, I need to know to what to cast (what is A).

Thanks!

Upvotes: 1

Views: 214

Answers (1)

Xharlie
Xharlie

Reputation: 2540

You can start with typeof(T) to get an instance of System.Type that represents T. Once you have that, you can check Type.IsGenericType to see if it really is a generic and then call Type.GetGenericArguments() to see what generic arguments were used.

For example, if T was List<int> IsGenericType would be true and GetGenericArguments() would return an array containing one element: System.Int32

For example, here is a snippet of code I wrote to see if a given type (variable type) is some implementation if IEnumerable<T> where T is not known. It first has to see if it is a generic, then work out whether it has only one argument, determine said argument and see if it implements the interface, given that argument:

if (type.IsGenericType)
{
    Type[] genericArguments = type.GetGenericArguments();
    if (genericArguments.Length == 1)
    {
        Type proposedEnumerable = typeof(IEnumerable<>).MakeGenericType(genericArguments);
        if (proposedEnumerable.IsAssignableFrom(type))
        {

For reference, see:

Upvotes: 4

Related Questions