How to get the type contained in a collection through reflection

In some part of my code, a collection of objects of type T is passed. I do not know which specific collector I will pass, except impements IEnumerable .

At runtime, I need to figure out what type is T (e.g. System.Double , System.String , etc.).

Is there any way to find out?

UPDATE . Perhaps I should clarify a little the context in which I work (Linq provider).

My function has a signature similar to the following, where I get the type of the collection as a parameter:

 string GetSymbolForType(Type collectionType) { } 

Is there any way from collectionType to get the contained type of objects?

+7
collections reflection c #
source share
7 answers

From Matt Warren's Blog :

 internal static class TypeSystem { internal static Type GetElementType(Type seqType) { Type ienum = FindIEnumerable(seqType); if (ienum == null) return seqType; return ienum.GetGenericArguments()[0]; } private static Type FindIEnumerable(Type seqType) { if (seqType == null || seqType == typeof(string)) return null; if (seqType.IsArray) return typeof(IEnumerable<>).MakeGenericType(seqType.GetElementType()); if (seqType.IsGenericType) { foreach (Type arg in seqType.GetGenericArguments()) { Type ienum = typeof(IEnumerable<>).MakeGenericType(arg); if (ienum.IsAssignableFrom(seqType)) { return ienum; } } } Type[] ifaces = seqType.GetInterfaces(); if (ifaces != null && ifaces.Length > 0) { foreach (Type iface in ifaces) { Type ienum = FindIEnumerable(iface); if (ienum != null) return ienum; } } if (seqType.BaseType != null && seqType.BaseType != typeof(object)) { return FindIEnumerable(seqType.BaseType); } return null; } } 
+14
source share
 myCollection.GetType().GetGenericArguments() 

will return an array of args types.

+8
source share
 Type t = null foreach(object o in list) { o.GetType(); } 

will give you the type of object.

Then you should probably check your desired types:

 if(t == typeof(myClass)) { dosomething(); } else if (t == typeof(myOtherClass)) { dosomethingelse(); } 
0
source share

You cannot use t.GetType () for this.

0
source share

Why not just implement an IEnumerable<T> instead? EG:

public void MyFunc<T>(IEnumerable<T> objects)

In addition, you better not check the type of each individual object using is or .GetType , and not try to process it from the container itself.

If this is not an option, and you really need to know the type of base container, you basically need to check with is to see which interfaces it implements (EG: IList<int> , etc.). Odds is the type of your array that will be shared, which means trying to work out the name from it before it. The data type will be pretty dirty.

0
source share

Well, I'm late here, but shouldn't work:

  public static bool ThatCollectionIsOfType<T>(IEnumerable<T> collection, Type got) { if (**typeof(T)** == got) //this line should be good to go... { return true; } } 
0
source share

I use dynamic alot and this is a problem from time to time.

Matt Davis nailed it, but you need an index :)

 public static void PopulateChildCollection<T>(T currentObject, string singlePropertyName) { dynamic currentObjectCollection = ReflectionTools.GetPropertyValue(currentObject, singlePropertyName); Type collectionType = currentObjectCollection.GetType().GetGenericArguments()[0]; 

The type will be what you expect, it is the type of the object contained in the collection, and not any of the common types surrounding it.

0
source share

All Articles