【问题标题】:Mono.Cecil type.IsAssignableFrom(derivedType) equivalentMono.Cecil type.IsAssignableFrom(derivedType) 等效
【发布时间】:2011-08-06 05:28:45
【问题描述】:

我正在使用 Mono.Cecil 在 Assembly 中查找派生自给定 on 的类型。 通常可以使用 IsAssignableFrom() 方法完成,但我无法在 Cecil 中找到它的等价物。 有没有这样的方法或其他方法来检查它? 谢谢 迈克

【问题讨论】:

  • 我想我记得看到过一个“摇滚”

标签: c# reflection inheritance cil mono.cecil


【解决方案1】:

继承检查和“赋值兼容性”检查实际上是不同的东西。是否要检查继承或“分配兼容性”?

赋值兼容性包括很多东西,包括有符号/无符号转换、枚举到基本类型的转换、charshort 的转换、泛型方差转换、从接口到 object 的转换、从数组到 IList 的转换和IList<T> 及其基本接口、数组协方差、约束的泛型参数,以及一大堆其他东西。

最好的办法是在 ECMA 规范中查找分配兼容性和“验证类型兼容性”规则以获取完整列表。

我猜您可能需要完整“作业兼容性检查”的一部分。

不幸的是,Cecil 没有任何方法可以为您实现这一点,但它确实为您提供了足够的信息来实现这一点。

在使用 cecil 实现类似的东西时,您确实需要小心。特别是 TypeReference 类有一个“Resolve”方法,在某些情况下需要调用(用于查找未解析类型引用的 TypeDefinition),但在其他情况下不能调用,因为它会深入挖掘类型树。您还需要处理“结构类型相等性”以比较泛型实例,并且在遍历类型层次结构时必须处理泛型参数替换。

【讨论】:

  • +1。很高兴看到一些代码示例。当然,如果没有详细的要求,很难推荐一种具体的方法(正如你的回答所解释的那样)。
  • 我有执行此操作的代码...但我无法与您分享...(至少现在不是)。我想传达的要点是:1)赋值兼容性不仅仅包括继承,2)继承检查需要检查的东西比你想象的要多,3)你需要考虑的一切都列在 ECMA 规范中,4)那里cecil API 中有一些你需要小心的陷阱。不过我不能给你代码。
  • 不用担心。反射/低级类型操作很难,对于这个答案(以及塞西尔本身)来说,对常见情况有帮助会很好。这个答案仍然很有用:)
【解决方案2】:

我从来没有对 Mono 做过任何事情,更不用说 Cecil,但是查看 GitHub 源代码,我猜您可能可以使用以下类型的 TypeDefinition 做一些事情:

public bool HasInterface(TypeDefinition type, string interfaceFullName)
{
  return (type.Interfaces.Any(i => i.FullName.Equals(interfaceFullName)) 
          || type.NestedTypes.Any(t => HasInterface(t, interfaceFullName)));
}

【讨论】:

  • +1。当我使用 Cecil 做一个项目时,我想为包装这种类型的功能的东西添加一个功能请求,但从来没有解决过它:) 另外,我忘记了为什么,在什么情况下,但你可能不得不做 null在枚举它们之前检查其中一些属性...
【解决方案3】:

查找类型 AType 的派生类型的一种方法是枚举程序集中定义的所有类型,并将它们的 BaseType 属性与类型 AType 进行比较。此方法在 ILSpy 中用于显示选定类型的派生类型。实现在 FindDerivedTypes 方法 (DerivedTypesTreeNode.cs) 中。要查找间接派生的类型,您必须遍历 BaseType 属性(使用 Resolve()),直到达到 AType 或 BaseType 等于 null。

【讨论】:

    【解决方案4】:

    ApiChange 工具确实使用 Mono Cecil。它可以找到使用您的类型的所有出现情况,包括使用命令从您的类型派生

    ApiChange.exe -whousestype “CommandBase”ApiChange.Api.dll -in ApiChange.Api.dll -excel

    您将获得一个 Excel 输出,其中包含您类型的所有用户的文件和行号。好像

    ApiChange.Api.dll   internal class ApiChange.Api.Scripting.CorFlagsCommand          Inherits from   internal class ApiChange.Api.Scripting.CommandBase  C:\Source\ApiChangeTooling\ApiChange.Api\src\Scripting\Commands\CorFlagsCommand.cs  
    ApiChange.Api.dll   internal class ApiChange.Api.Scripting.WhoImplementsInterfaceCommand            Inherits from   internal class ApiChange.Api.Scripting.CommandBase  C:\Source\ApiChangeTooling\ApiChange.Api\src\Scripting\Commands\WhoImplementsInterfaceCommand.cs    
    ApiChange.Api.dll   internal class ApiChange.Api.Scripting.DiffAssembliesCommand            Inherits from   internal class ApiChange.Api.Scripting.CommandBase  C:\Source\ApiChangeTooling\ApiChange.Api\src\Scripting\Commands\DiffAssembliesCommand.cs    
    

    使用Cecil的实际代码位于WhoUsesType.cs

    你的, 阿洛伊斯克劳斯

    【讨论】:

      猜你喜欢
      • 2021-10-09
      • 1970-01-01
      • 2011-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多