2011-04-15 8 views
10

Estoy usando Mono.Cecil para encontrar tipos en Assembly derivados de given on. Normalmente se puede hacer con el método IsAssignableFrom(), pero no puedo creer que sea equivalente en Cecil. ¿Existe algún método u otro método para verificarlo? Gracias MikeMono.Cecil tipo.IsAssignableFrom (derivedType) equivalent

+0

Creo que recuerdo haber visto una 'Roca' para ese – sehe

Respuesta

2

que nunca he hecho nada con Mono, y mucho menos Cecil, pero mirando a través de la fuente de GitHub, supongo que probablemente podría hacer algo con un TypeDefinition del tipo:

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

+1. Cuando hice un proyecto con Cecil, pensé en agregar una solicitud de función para algo que incluyera este tipo de funcionalidad, pero nunca lo hice :) Además, no recuerdo por qué, y en qué casos, pero podría tener que hacer nulo comprueba algunas de estas propiedades antes de enumerarlas ... –

1

Un método para buscar tipos derivados de tipo AType es enumerar todos los tipos definidos en el conjunto y comparar su propiedad BaseType con el tipo AType. Este método se usa en ILSpy para mostrar tipos derivados de un tipo seleccionado. La implementación está en el método FindDerivedTypes (DerivedTypesTreeNode.cs). Para encontrar tipos derivados indirectamente, debe iterar sobre la propiedad BaseType (utilizando Resolve()) hasta que se llegue al AType o BaseType sea nulo.

0

La herramienta ApiChange utiliza Mono Cecil. Se puede encontrar todas las ocurrencias donde se utilice el tipo incluyendo derivación de su tipo con el comando

ApiChange.exe -whousestype "CommandBase" ApiChange.Api.dll -en ApiChange.Api.dll -Excel

obtendrá una salida de Excel con el número de archivo y línea de todos los usuarios de su tipo. Parece que

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  

El código real usando Cecil está situado en WhoUsesType.cs

Suyo, Alois Kraus

4

cheques y cheques de herencia "de compatibilidad de asignación" en realidad son cosas diferentes. ¿Desea verificar la herencia o la "compatibilidad de asignación"?

la compatibilidad de asignación incluye muchas cosas, incluyendo conversiones firmados/no firmados, enumeración a las conversiones de tipos de base, char a short conversiones, las conversiones de varianza genéricos, las conversiones de interfaces para object, a partir de las matrices a IList y IList<T> y sus interfaces base, la covarianza de la matriz, el parámetro genérico de las restricciones y un montón de otras cosas.

Su mejor opción es buscar las reglas de compatibilidad de asignación y "compatibilidad de tipo de verificación" en las especificaciones de ECMA para obtener una lista completa.

Supongo que para sus necesidades particulares querrá un subconjunto de las "comprobaciones de compatibilidad de tareas" completas.

Desafortunadamente, Cecil no tiene ningún método que implementará esto para usted, pero proporciona suficiente información para que pueda implementarlo usted mismo.

Debe tener cuidado al implementar algo como esto usando cecil. En particular, la clase TypeReference tiene un método "Resolve" al que debe llamar en algunos casos (para encontrar el TypeDefinition para una referencia de tipo no resuelto), pero que no puede invocar en otros casos, ya que cavará demasiado a través del tipo árbolTambién necesitará lidiar con la "igualdad de tipo estructural" para comparar instantaciones genéricas, y tendrá que manejar la sustitución de parámetros genéricos al subir las jerarquías de tipos.

+0

+1. Sería bueno ver algunos ejemplos de código. Por supuesto, sin requisitos detallados, es difícil recomendar un enfoque específico (como explica su respuesta). –

+0

Tengo un código que hace esto ... pero no puedo compartirlo contigo ... (al menos no ahora). Los puntos principales que quería transmitir son los siguientes: 1) La compatibilidad de asignación abarca más que la herencia, 2) Las verificaciones de herencia requieren el control de más cosas de las que se pensaba, 3) Todo lo que necesita considerar se detalla en la especificación de ECMA, 4) hay algunas trampas en la API cecil de la que debes tener cuidado. Aunque no puedo darte código. –

+0

Sin preocupaciones. La manipulación de reflejos/tipos de bajo nivel es difícil, y tener ayuda para casos comunes sería bueno para los propósitos de esta respuesta (y también para el propio Cecil). Esta respuesta todavía es útil como es :) –