获取.NET类层次结构

时间:2017-03-07 08:52:15

标签: c# .net structure hierarchy

我试图获取.NET Framework中的所有对象及其命名空间的层次结构顺序,并将它们放入树结构或某种用于C#中的学术目的。我正在尝试为特定的.NET框架平台执行此操作。有没有办法做这样的事情?

请求:列出System.Threading命名空间

下的所有内容(类,枚举,结构等)

结果:

构造

  • AbandonedMutexException
  • 互锁
  • blah blah

结构:

  • AsyncFlowControl
  • 的CancellationToken
  • blah blah

代表:

  • ContexCallback
  • 的ThreadStart
  • blah blah

枚举:

  • blah blah

Pretty much what I want is something like this. - MSDN

非常感谢。

编辑:我不是要求代码示例或有人为我编写代码 - 我只是无法弄清楚从哪里开始所以我正在寻找提示。

3 个答案:

答案 0 :(得分:4)

以下是有关如何入门的一些指导原则:

  1. 您需要使用Reflection,即System.Reflection命名空间(AssemblyConstructorInfoPropertyInfo等类别中的类。正如MSDN上所述:

      

    System.Reflection命名空间中的类与System.Type一起使您能够获取有关已加载程序集及其中定义的类型的信息,例如类,接口,和价值类型。您还可以在运行时使用反射创建类型实例,并调用并访问它们

  2. 首先获取Assembly类的实例。您可以从要访问的程序集中传递类型(任何类型,例如System.Threading.Barrier)并使用Assembly.GetAssembly

    var assembly = Assembly.GetAssembly(typeof(System.Threading.Barrier));
    

    或者,如果您要遍历.dll文件的文件夹,则可以使用Assembly.LoadFrom

    var assembly = Assembly.LoadFrom("path-to-System.Threading.dll");
    
  3. 获得程序集实例后,您将需要遍历这些类型并对它们进行进一步的反思:

    foreach (var type in assembly.GetTypes())
    {
        var constructors = type.GetConstructors();
        var fields = type.GetFields();
        var properties = type.GetProperties();
        ...
    }
    
  4. Type类除了这些方法外,还包含各种属性,可让您查看指定的类型是class还是struct({{1 }},Type.IsValueTypeType.IsInterface等),查看一种类型是否继承或实现了另一种类型(Type.IsAbstractType.IsAssignableFrom(otherType))和类似的东西。

答案 1 :(得分:2)

有人(Groo)已经认识到"理论"回答你应该怎么做,但请注意至少有两个强烈的警告:

  • 任何Microsoft程序集都可以包含System.Threading类(技术上任何程序集都可以包含它,甚至包含它,但这样做是不礼貌的)
  • 如果你想探索一个" base"来自.NET的不同版本的程序集( mscorlib System ,...),那么您需要使用Mono.Cecil或类似程序库,因为使用Reflection,你不能加载不同版本的基本组件而不是你正在运行的版本。

现在有一些非常简单的代码:

var assemblyNames = new[]
{
    "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
    "System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
    "System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
};

var nss = new[]
{
    "System.Threading"
};


// Begin real code

var assemblies = Array.ConvertAll(assemblyNames, Assembly.Load);
var nss2 = Array.ConvertAll(nss, x => x + ".");

var types = assemblies.SelectMany(x => x.ExportedTypes).Where(x => nss2.Any(y => x.FullName.StartsWith(y))).ToArray();

// The Delegate check is taken from http://mikehadlow.blogspot.it/2010/03/how-to-tell-if-type-is-delegate.html
var classes = types.Where(x => x.IsClass && !typeof(Delegate).IsAssignableFrom(x)).ToArray();
var structs = types.Where(x => x.IsValueType && !x.IsEnum).ToArray();
var enums = types.Where(x => x.IsEnum).ToArray();
var delegates = types.Where(x => x.IsClass && typeof(Delegate).IsAssignableFrom(x)).ToArray();

// There is a DeclaringType property to see what Type is declaring them
var constructors = types.SelectMany(x => x.GetConstructors(BindingFlags.Public | BindingFlags.Instance)).ToArray();

答案 2 :(得分:1)

如果您可以get hold of the corresponding XML file获得您感兴趣的框架,您可能会发现转换它比直接从代码中提取此信息更容易。