10

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

4

4 回答 4

4

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

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

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

我猜你的特殊需求需要完整的“分配兼容性检查”的一部分。

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

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

于 2011-05-10T06:29:10.877 回答
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)));
}
于 2011-04-18T07:47:43.347 回答
1

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

于 2011-04-20T18:33:22.747 回答
-1

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

你的,阿洛伊斯克劳斯

于 2011-04-23T22:06:22.040 回答