打印C#中 class
类型的全部子类型:
Console.WriteLine(TypeTree.CreateTypeTree(typeof(Object)).ToString());
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
public class TypeTree
{
public static TypeTree CreateTypeTree(Type rootType,
bool useFullTypeName = true, IEnumerable<Type> scope = null)
{
if (rootType == null)
throw new ArgumentNullException(nameof(rootType));
if (!rootType.IsClass)
throw new ArgumentException("Root type must be class type.", nameof(rootType));
scope ??= from assembly in AppDomain.CurrentDomain.GetAssemblies()
from type in assembly.GetTypes()
where rootType.IsAssignableFrom(type)
select type;
return new TypeTree(rootType, scope.ToList(), useFullTypeName);
}
public bool UseFullTypeName {
get; }
public Type Type {
get; }
public IReadOnlyCollection<TypeTree> SubTrees => _subTrees;
private readonly LinkedList<TypeTree> _subTrees = new LinkedList<TypeTree>();
private TypeTree(Type rootType, List<Type> scope, bool useFullTypeName)
{
UseFullTypeName = useFullTypeName;
Type = rootType;
scope.Remove(Type);
FindDirectChildRecursively(this, scope);
}
public override string ToString()
{
var treeBuilder = new StringBuilder(5000);
var indentBuilder = new StringBuilder(10);
BuildTree(treeBuilder, indentBuilder, 0, this);
return treeBuilder.ToString();
}
private static void FindDirectChildRecursively(TypeTree rootNode, List<Type> scope)
{
var subTypes = (from type in scope
where type.BaseType != null &&
(type.BaseType == rootNode.Type ||
(type.BaseType.IsGenericType &&
type.BaseType.GetGenericTypeDefinition() == rootNode.Type))
select type).ToArray();
foreach (var subType in subTypes)
{
var subTree = new TypeTree(subType, scope, rootNode.UseFullTypeName);
rootNode._subTrees.AddLast(subTree);
}
}
private static void BuildTree(StringBuilder treeBuilder,
StringBuilder indentBuilder, int indent, TypeTree node)
{
const string IndentSymbol = " ";
indentBuilder.Clear();
for (int i = 0; i < indent; i++)
{
indentBuilder.Append(IndentSymbol);
}
treeBuilder.Append(indentBuilder);
treeBuilder.AppendLine(node.UseFullTypeName ? node.Type.FullName : node.Type.Name);
foreach (var subTree in node.SubTrees)
{
BuildTree(treeBuilder, indentBuilder, indent + 1, subTree);
}
}
}