Я использую Mono.Cecil для поиска типов в сборке, которые получены из заданного. Нормально это можно сделать с помощью метода IsAssignableFrom(), но я не могу сгладить его эквивалент в Сесиле. Есть ли такой способ или другой способ проверить его? благодаря Mike
Тип Mono.Cecil.IsAssignableFrom(производныйType) эквивалент
Ответ 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
С уважением, Алоис Краус