Elvedin Hamzagic
Elvedin Hamzagic

Reputation: 855

Get type of elements in a List derived from List<T> in C#

Lets say that I have classes which derive from List<T>:

public class StringList : List<String> {}
public class NameList : StringList {}

public class IntList : List<int> {}

Now I have a generic method which expects type List<T>:

public static Method<T>() { ... }

How can I determine the type of elements contained in a list in this method, i.e. how to get the generic argument type in a derived class?

For base class I can call typeof(T>.GetGenericArguments(), but for derived class it returns zero size.

PS: In my concrete situation the type which method expects is not exactly List<T>, but IList.

Upvotes: 1

Views: 358

Answers (2)

Cheng Chen
Cheng Chen

Reputation: 43531

If you want both the type of the list and the element type of the list at compile time, your Method must have two generic definitions like this:

public static void Method<T, E>(T list) where T : List<E> 
{ 
    // example1
    // T is List<int> and E is int

    // example2
    // T is NameList and E is String
}

Method<List<int>, int>(new List<int>());   //example1
Method<NameList, string>(new NameList());  //example2

Upvotes: 2

Rob
Rob

Reputation: 27377

You can write the method like this:

public static void Method<T>(List<T> thing) (or IList<T>)
{
    //Here, `T` is the type of the elements in the list
}

Of if you need a reflection-based check:

public static void Method(Type myType) 
{
    var thing = myType.GetInterfaces()
        .Where(i => i.IsGenericType)
        .Where(i => i.GetGenericTypeDefinition() == typeof(IList<>))
        .FirstOrDefault()
        .GetGenericArguments()[0];
}

Note that you'll need appropriate sanity checks here (rather than FirstOrDefault() and 0 indexing)

Upvotes: 3

Related Questions