From f64c2b5e6b5fd1d11109931aa1b297e12d6053ed Mon Sep 17 00:00:00 2001 From: David Hall Date: Mon, 25 Mar 2019 17:34:43 -0700 Subject: [PATCH] Added FindElementType extension method for Type. --- Core/Extensions/ReflectionExtensions.cs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/Core/Extensions/ReflectionExtensions.cs b/Core/Extensions/ReflectionExtensions.cs index 4ebcb9d2..5ecfa252 100644 --- a/Core/Extensions/ReflectionExtensions.cs +++ b/Core/Extensions/ReflectionExtensions.cs @@ -32,6 +32,33 @@ namespace Vanara.Extensions public static IEnumerable GetCustomAttributes(this Type type, bool inherit = false, Func predicate = null) where TAttr : Attribute => type.GetCustomAttributes(typeof(TAttr), inherit).Cast().Where(predicate ?? (a => true)); + /// Finds the type of the element of a type. Returns null if this type does not enumerate. + /// The type to check. + /// The element type, if found; otherwise, . + public static Type FindElementType(this Type type) + { + if (type.IsArray) + return type.GetElementType(); + + // type is IEnumerable; + if (ImplIEnumT(type)) + return type.GetGenericArguments().First(); + + // type implements/extends IEnumerable; + var enumType = type.GetInterfaces().Where(ImplIEnumT).Select(t => t.GetGenericArguments().First()).FirstOrDefault(); + if (enumType != null) + return enumType; + + // type is IEnumerable + if (IsIEnum(type) || type.GetInterfaces().Any(IsIEnum)) + return typeof(object); + + return null; + + bool IsIEnum(Type t) => t == typeof(System.Collections.IEnumerable); + bool ImplIEnumT(Type t) => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IEnumerable<>); + } + /// Gets a named property value from an object. /// The expected type of the property to be returned. /// The object from which to retrieve the property.