Mono.Cecil type.IsAssignableFrom (производный тип) эквивалент - PullRequest
10 голосов
/ 15 апреля 2011

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

Ответы [ 4 ]

4 голосов
/ 10 мая 2011

Проверки наследования и проверки «совместимости присваивания» на самом деле разные вещи.Вы хотите проверить наследование или «совместимость присваивания»?

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

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

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

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

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

2 голосов
/ 18 апреля 2011

Я никогда ничего не делал с Mono, не говоря уже о Сесиле, но, просматривая исходный код 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 голос
/ 20 апреля 2011

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

0 голосов
/ 24 апреля 2011

Инструмент 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

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

...