public static IType GetElementTypeFromIEnumerable(this IType collectionType, ICompilation compilation, bool allowIEnumerator, out bool?isGeneric) { bool foundNonGenericIEnumerable = false; foreach (IType baseType in collectionType.GetAllBaseTypes()) { ITypeDefinition baseTypeDef = baseType.GetDefinition(); if (baseTypeDef != null) { KnownTypeCode typeCode = baseTypeDef.KnownTypeCode; if (typeCode == KnownTypeCode.IEnumerableOfT || (allowIEnumerator && typeCode == KnownTypeCode.IEnumeratorOfT)) { ParameterizedType pt = baseType as ParameterizedType; if (pt != null) { isGeneric = true; return(pt.GetTypeArgument(0)); } } if (typeCode == KnownTypeCode.IEnumerable || (allowIEnumerator && typeCode == KnownTypeCode.IEnumerator)) { foundNonGenericIEnumerable = true; } } } // System.Collections.IEnumerable found in type hierarchy -> Object is element type. if (foundNonGenericIEnumerable) { isGeneric = false; return(compilation.FindType(KnownTypeCode.Object)); } isGeneric = null; return(SpecialType.UnknownType); }
/// <summary> /// Returns the element type, if <paramref name="type"/> is a nullable type. /// Otherwise, returns the type itself. /// </summary> public static IType GetUnderlyingType(IType type) { if (type == null) { throw new ArgumentNullException("type"); } ParameterizedType pt = type.SkipModifiers() as ParameterizedType; if (pt != null && pt.TypeParameterCount == 1 && pt.GenericType.IsKnownType(KnownTypeCode.NullableOfT)) { return(pt.GetTypeArgument(0)); } else { return(type); } }