Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mono.Cecil type.IsAssignableFrom(derivedType) equivalent

I'm using Mono.Cecil to find types in Assembly that are derived from given on. Normaly it can be done with IsAssignableFrom() method, but I cannot fing it's equivalent in Cecil. Is there any such method or other way to check it? Thanks Mike

like image 235
stachu Avatar asked Apr 15 '11 10:04

stachu


3 Answers

Inheritance checks and "assignment compatibility" checks are actually different things. Do you want to check inheritance or "assignment compatibility"?

Assignment compatibility includes a lot of things, including signed / unsigned conversions, enum to base type conversions, char to short conversions, generic variance conversions, conversions from interfaces to object, from arrays to IList and IList<T> and their base interfaces, array covariance, generic parameter to constraints, and a whole bunch of other stuff.

Your best bet is to lookup the assignment compatability and "verification type compatibility" rules int the ECMA spec for a complete list.

I'm guessing for your particular needs you'll want some subset of the full "assignment compatibility checks".

Unfortunately, Cecil doesn't have any methods that will implement this for you, but it does provide enough information for you to implement this your self.

You do need to be careful when implementing something like this using cecil. In particular the TypeReference class has a "Resolve" method that you need to call in some cases (for finding the TypeDefinition for an unresolved type reference), but that you can't call in other cases, because it will dig too far through the type tree. You'll also need to deal with "structural type equality" for comparing generic instantations, and will have to handle generic parameter substitution when walking up type hierarchies.

like image 196
Scott Wisniewski Avatar answered Nov 06 '22 21:11

Scott Wisniewski


I've never done anything with Mono, let alone Cecil, but looking through the GitHub source, I'm guessing you could probably do something with a TypeDefinition of the type:

public bool HasInterface(TypeDefinition type, string interfaceFullName)
{
  return (type.Interfaces.Any(i => i.FullName.Equals(interfaceFullName)) 
          || type.NestedTypes.Any(t => HasInterface(t, interfaceFullName)));
}
like image 27
Matthew Abbott Avatar answered Nov 06 '22 21:11

Matthew Abbott


One method to find derived types of type AType is to enumerate all types defined in the assembly and compare their BaseType property to the type AType. This method is used in ILSpy to show derived types of a selected type. Implementation is in FindDerivedTypes method (DerivedTypesTreeNode.cs). To find types derived indirectly you have to iterate over BaseType property (using Resolve()) until the AType is reached or BaseType is equal to null.

like image 1
arturek Avatar answered Nov 06 '22 23:11

arturek