【杂项|C#|自用工具】打印class类型的全部子类型

打印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);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_21397217/article/details/126536885