How to get array element type from array in .net

Say I have an object of type System.String[] . I can query an object of type to determine if it is an array

 Type t1 = typeof(System.String[]); bool isAnArray = t1.IsArray; // should be true 

How do I get an object of an array element type from t1

 Type t2 = ....; // should be typeof(System.String) 
+51
reflection types
Nov 09 '10 at 1:54
source share
3 answers

You can use the instance method of Type.GetElementType for this purpose.

 Type t2 = t1.GetElementType(); 

[Returns] the type of the object covered by or referred to by the current array, pointer or reference type, or null if the current type is not an array or pointer or passed by reference or is a generic type or type parameter in the definition of a generic type or generic method.

+86
Nov 09 '10 at 1:58
source share
— -

Thanks to the @psaxton comment , indicating the difference between arrays and other collections. As an extension method:

 public static class TypeHelperExtensions { /// <summary> /// If the given <paramref name="type"/> is an array or some other collection /// comprised of 0 or more instances of a "subtype", get that type /// </summary> /// <param name="type">the source type</param> /// <returns></returns> public static Type GetEnumeratedType(this Type type) { // provided by Array var elType = type.GetElementType(); if (null != elType) return elType; // otherwise provided by collection var elTypes = type.GetGenericArguments(); if (elTypes.Length > 0) return elTypes[0]; // otherwise is not an 'enumerated' type return null; } } 

Using:

 typeof(Foo).GetEnumeratedType(); // null typeof(Foo[]).GetEnumeratedType(); // Foo typeof(List<Foo>).GetEnumeratedType(); // Foo typeof(ICollection<Foo>).GetEnumeratedType(); // Foo typeof(IEnumerable<Foo>).GetEnumeratedType(); // Foo // some other oddities typeof(HashSet<Foo>).GetEnumeratedType(); // Foo typeof(Queue<Foo>).GetEnumeratedType(); // Foo typeof(Stack<Foo>).GetEnumeratedType(); // Foo typeof(Dictionary<int, Foo>).GetEnumeratedType(); // int typeof(Dictionary<Foo, int>).GetEnumeratedType(); // Foo, seems to work against key 
+12
Feb 24 '14 at 18:21
source share

Thanks to @drzaus for his good answer , but it can be compressed in oneliner (plus check for null and IEnumerable ):

 public static Type GetEnumeratedType(this Type type) => type?.GetElementType() ?? typeof(IEnumerable).IsAssignableFrom(type) ? type.GenericTypeArguments.FirstOrDefault() : null; 

Added null checkers to avoid an exception, maybe I shouldn't (feel free to remove the Null Conditional Operators ). A filter has also been added, so the function only works with collections, not universal types.

And keep in mind that this can also be tricked by implemented subclasses that change the collection item, and the developer decided to move the generic-type argument of the collection to a later position.

+1
May 7 '17 at 12:02 a.m.
source share



All Articles