やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

指定した型を継承した型をツリー構造で取得する

 前回のツリー版。

成果物

前回

コード

class Program
{
    static void Main(string[] args)
    {
        ...
        Console.WriteLine("Aの子孫すべてをツリーで。");
        TypeNode node = AssemblyUtils.GetInheritanceTypeTree<A>();
        ShowNode(node);
    }
    private static void ShowNode(TypeNode node, int index=0)
    {
        if (null != node) { Console.WriteLine($"{(new string('*', index)).Replace("*", "    ")}{node.Type.Name}"); }
        if (null != node?.Children) {
            index++;
            foreach (var n in node.Children) { ShowNode(n, index); }
        }
    }
}
class A {}
class A1 : A {}
class A2 : A {}
class A11 : A1 {}
class B {}
class B1 : B {}
public static class AssemblyUtils
{
    // 指定した型を継承した子型を返す。(直下の子のみ。子孫以下であっても対象外)
    public static Type[] GetChildren<T>()
    {
        return _GetChildren(typeof(T)).ToArray();
    }
    private static IEnumerable<Type> _GetChildren(Type type)
    {
        return Assembly.GetExecutingAssembly().GetTypes().Where(c => c.BaseType == type);
    }
    ...
    // 指定した型を継承した子孫をツリーで返す
    public static TypeNode GetInheritanceTypeTree<T>()
    {
        return GetInheritanceTypeNode(typeof(T));
    }
    private static TypeNode GetInheritanceTypeNode(Type type)
    {
        var children = _GetChildren(type);
        var node = new TypeNode(type);
        if (null == children) { return node; }
        else {
            foreach (var child in children) {
                node.Add(GetInheritanceTypeNode(child));
            }
            return node;
        }
    }
}
public class TypeNode
{
    public Type Type { get; private set; }
    public TypeNode(Type type) {
        children = new List<TypeNode>();
        Children = new ReadOnlyCollection<TypeNode>(children);
        this.Type = type;
    }
    protected IList<TypeNode> children { get; set; }
    public IReadOnlyList<TypeNode> Children { get; }
    public TypeNode Add(TypeNode node) { children.Add(node); return this; }
}

出力結果

Aの子孫すべてをツリーで。
A
    A1
        A11
    A2

 クラスの継承関係は以下。

  • A
    • A1
      • A11
    • A2
  • B
    • B1

所感

 継承図を作るライブラリなど書けそう。以下も参考にして。

対象環境

$ uname -a
Linux raspberrypi 4.19.42-v7+ #1218 SMP Tue May 14 00:48:17 BST 2019 armv7l GNU/Linux