【问题标题】:Determine Class Associations using Reflection使用反射确定类关联
【发布时间】:2012-05-10 06:34:11
【问题描述】:

我正在研究一种提取彼此之间的所有类关联的解决方案。如果我们在对象浏览器中单击一个类,我们可以看到选项Find All References。我想要类似的东西来找到一个类与其他类的关联。我们如何使用Reflection 找到它们?

我对提取感兴趣

  1. 组成关系:
  2. 聚合关系
  3. 关联关系
  4. 继承

【问题讨论】:

  • .NET 中的反射仅检查元数据,而不检查 IL。您必须使用 Mono.Cecil 之类的东西来检查一个类及其成员,以查看它正在使用哪些类型。
  • IL 是什么意思?并且有任何想法 ab codeproject.com/Articles/17823/…

标签: c# uml class-diagram class-reference class-relationship


【解决方案1】:

您可以使用Reflection 来列出类的所有属性、字段和方法(以及更多)。您必须检查这些并确定它们的类型和参数列表。从 System 命名空间中丢弃类型可能是个好主意。

Type t = typeof(MyClass);

// Determine from which type a class inherits
Type baseType = t.BaseType;

// Determine which interfaces a class implements
Type[] interfaces = t.GetInterfaces();

// Get fields, properties and methods
const BindingFlags bindingFlags =
    BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
FieldInfo[] fields = t.GetFields(bindingFlags);
PropertyInfo[] properties = t.GetProperties(bindingFlags);
MethodInfo[] methods = t.GetMethods(bindingFlags);

foreach (var method in methods) {
    // Get method parameters
    ParameterInfo[] parameters = method.GetParameters();
}

Intellisense 会告诉你(几乎)FieldInfoPropertyInfoMethodInfoParameterInfo 的所有秘密。您还可以考虑检查类、事件等的通用参数。

【讨论】:

  • 这只会检索公开暴露的类型;您将能够回答“X 公开了哪些类型”,而不是“X 使用了哪些类型”。
  • BindingFlags.NonPublic 也会显示非公开成员;但是,以某种方式在本地使用的局部变量和类型不能通过反射列出,但它们无论如何都不会成为组合、聚合、关联和继承的一部分。
【解决方案2】:

您需要解析生成的 IL 代码,最好了解它们的工作原理。您可以通过调用MethodBase.GetMethodBody 后跟MethodBody.GetILAsByteArray 来检索IL 代码。

您需要根据OpCodes 枚举解析每个字节。您还需要处理所有操作码数据,例如偏移量和令牌,因为您不应该将它们解析为实际操作码。以OpCodes.Ldstr 操作码为例;它由 0x72 后跟一个令牌组成。这个标记是四个字节,应该被解析为 Int32,并且可以使用 Module.ResolveString(因为您知道 ldstr 有一个字符串标记)。您可以从Assembly.AssemblyManifestModule 获取Module 实例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-01
    • 2012-07-11
    • 1970-01-01
    相关资源
    最近更新 更多