views:

15188

answers:

8

Hello,

Let say I have a List< T > abc = new List< T >; inside a class public class MyClass<T>//.... Later, when I initialize the class the T because MyTypeObject1. So I have a generic list of List< MyTypeObject1 >.

I would like to know, what type of object the list of my class contain. Example, the list called abc contain what type of object? I cannot do abc[0].GetType(); because the list might contain 0 element. How can I do it?

+21  A: 

(note: I'm assuming that all you know is object or IList or similar, and that the list could be any type at runtime)

If you know it is a List<T>, then:

Type type = abc.GetType().GetGenericArguments()[0];

Another option is to look at the indexer:

Type type = abc.GetType().GetProperty("Item").PropertyType;
Marc Gravell
Type type = abc.GetType().GetGenericArguments()[0]; ==> Out of bounds array index...
Daok
@Daok : then it isn't a List<T>
Marc Gravell
Need something for BindingList or List or whatever object that hold a <T>. What I am doing use a custom BindingListView<T>
Daok
Sorry haven't be enough specific in the question. Thx Marc for your answer.
Daok
Anything that is generic with one type argument should work.
Marc Gravell
Give a try with BindingList<T>, our BindingListView<T> inherit from BindingList<T> and both I have try both of your option and it doesn't work. I might do something wrong... but I think this solution work for the type List<T> but not other type of list.
Daok
Type type = abc.GetType().GetProperty("Item").PropertyType; return BindingListView<MyObject> instead of MyObject...
Daok
@Daok - do you have code to reproduce that?
Marc Gravell
I will try to create a code snippet that reproduce that. Might be tonight or tomorrow.
Daok
Just a small addition: GetProperty("Item") will throw a System.Reflection.AmbiguousMatchException in the (rare?) case if there is more than one indexer. I handle that case with a try..catch: Try GetProperty, otherwise revert to GetGenericArguments.
Michael Stum
The second form does not work with obfuscation I guess. Thank you for the anwer anyway, it is exactly what I was looking for.
macias
+6  A: 

Try

list.GetType().GetGenericArguments()
Rauhotz
This is not working.... GetGenericArguments return System.Type[0]
Daok
new List<int>().GetType().GetGenericArguments() returns System.Type[1] here with System.Int32 as entry
Rauhotz
nice one just what I was looking for
Calanus
+30  A: 

If I understand correctly, your list has the same type parameter as the container class itself. If this is the case, then:

Type typeParameterType = typeof(T);

If you are in the lucky situation of having object as a type parameter, see Marc's answer.

DrJokepu
Lol - yes, very true; I assumed that the OP only had `object`, `IList`, or similar - but this could very well be the right answer.
Marc Gravell
This is working very well.
Daok
A: 

May I make a question? Why do you want to know the type of T? Teoretically, generics are made just to remove the need to know the element detail implementation...

ZeD
The grid has a constructor that require the type of object to do special manipulation...
Daok
@ZeD: This belongs into a comment not in an answer.
J. Random Coder
A: 

typeof(T) should do what you need.

You exactly copy paste the answer of the guy who answer me 1 month ago lol
Daok
A: 

Type:

type = list.AsEnumerable().SingleOrDefault().GetType();
Ferenc Mucsi
This would throw a NullReferenceException if the list has no elements inside it for it to test against.
rossisdead
A: 

Consider this: I use it to export 20 typed list by same way:

    private void Generate<T>()
    {
        T item = (T)Activator.CreateInstance(typeof(T));

        ((T)item as DemomigrItemList).Initialize();

        Type type = ((T)item as DemomigrItemList).AsEnumerable().FirstOrDefault().GetType();
        if (type == null) return;
        if (type != typeof(account)) //account is listitem in List<account>
        {
            ((T)item as DemomigrItemList).CreateCSV(type);
        }
    }
Ferenc Mucsi
A: 

Hello, The GetGenericArgument() method has to be set on the Base Type of your instance (whose class is a generic class myClass)

otherwise, it returns a type[0]

ex: Myclass instance = new Myclass(); Type[] listTypes = typeof(instance).BaseType.GetGenericArguments();

Thomas