Подтвердить что ты не робот

Тип Mono.Cecil.IsAssignableFrom(производныйType) эквивалент

Я использую Mono.Cecil для поиска типов в сборке, которые получены из заданного. Нормально это можно сделать с помощью метода IsAssignableFrom(), но я не могу сгладить его эквивалент в Сесиле. Есть ли такой способ или другой способ проверить его? благодаря Mike

4b9b3361

Ответ 1

Я никогда ничего не делал с Моно, не говоря уже о Сесиле, но просматривая источник 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)));
}

Ответ 2

Проверка наследования и проверка совместимости присваивания - это фактически разные вещи. Вы хотите проверить наследование или "совместимость присваивания"?

Совместимость присваивания включает в себя множество вещей, включая конверсии с подписью/без знака, преобразования перечисления в базовый тип, преобразования char в short, общие преобразования дисперсий, преобразования с интерфейсов в object, от массивов до IList и IList<T> и их базовые интерфейсы, ковариацию массива, общий параметр для ограничений и целую кучу других вещей.

Лучше всего искать соответствие совместимости назначений и правила совместимости типов проверки в спецификации ECMA для полного списка.

Я предполагаю, что для ваших конкретных потребностей вам понадобится некоторое подмножество полных "проверок совместимости назначений".

К сожалению, у Cecil нет каких-либо методов, которые будут реализовывать это для вас, но он предоставляет достаточно информации для вас, чтобы реализовать это самостоятельно.

Вам нужно быть осторожным при реализации чего-то подобного с помощью cecil. В частности, класс TypeReference имеет метод "Resolve", который вам нужно вызвать в некоторых случаях (для поиска TypeDefinition для неразрешенной ссылки типа), но вы не можете вызывать в других случаях, потому что он будет копать слишком далеко через тип дерево. Вам также нужно будет иметь дело с "структурным равенством типа" для сравнения генерирующих макетов, и им придется обрабатывать подстановку общих параметров при иерархиях ходячих типов.

Ответ 3

Одним из методов поиска производных типов типа AType является перечисление всех типов, определенных в сборке, и сравнение их свойства BaseType с типом AType. Этот метод используется в ILSpy для отображения производных типов выбранного типа. Реализация выполняется в методе FindDerivedTypes (DerivedTypesTreeNode.cs). Чтобы найти типы, полученные косвенным образом, вы должны перебирать свойство BaseType (используя Resolve()) до тех пор, пока AType не будет достигнут, или BaseType не будет равен нулю.

Ответ 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

С уважением, Алоис Краус