public static IEnumerable <Type> GetHierarchy(Type input, TypeHierarchyOrder typeHierarchyOrder = TypeHierarchyOrder.BottomUp) { // Traverse up the inheritence hierarchy but return // in top-down order if (input == null) { return(Enumerable.Empty <Type>()); } var types = new QueueOrStack <Type>(typeHierarchyOrder); AddTypeAndInterfaces(types, input); Type baseType = input; while ((baseType = baseType.BaseType) != null) { AddTypeAndInterfaces(types, baseType); } return(types.Distinct().ToList()); }
private static void AddTypeAndInterfaces(QueueOrStack <Type> types, Type type) { // Because we're adding to a stack, the interfaces (more abstract) // will actually be returned *after* the implementation (less abstract) types.Add(type); var interfaces = type.GetInterfaces().ToList(); interfaces.Sort( (type1, type2) => { if (type1 == type2) { return(string.Compare(type1.FullName, type2.FullName, StringComparison.Ordinal)); } return(type2.IsAssignableFrom(type1) ? 1 : -1); }); for (int i = interfaces.Count - 1; i >= 0; i--) { types.Add(interfaces[i]); } }