2011-02-07 16 views

Respuesta

7

No, Cecil no proporciona dicho método, porque Cecil nos proporciona solo los metadatos CIL tal como están. (Existe el proyecto Cecil.Rocks, que contiene algunos métodos de extensión útiles, pero no este)

En MSIL los métodos tienen un atributo 'sobrescribe', que contiene referencias a métodos que este método anula (en Cecil hay una Anulaciones de propiedad en la clase MethodDefinition). Sin embargo, este atributo se usa solo en algunos casos especiales, como la implementación de interfaz explícita. Por lo general, este atributo se deja vacío y los métodos que se reemplazan por el método en cuestión se basan en las convenciones. Estas convenciones se describen en el estándar ECMA CIL. En resumen, un método anula los métodos que tienen el mismo nombre y la misma firma.

Los siguientes fragmentos de código pueden ayudar a usted, así como la discusión: http://groups.google.com/group/mono-cecil/browse_thread/thread/b3c04f25c2b5bb4f/c9577543ae8bc40a

public static bool Overrides(this MethodDefinition method, MethodReference overridden) 
    { 
     Contract.Requires(method != null); 
     Contract.Requires(overridden != null); 

     bool explicitIfaceImplementation = method.Overrides.Any(overrides => overrides.IsEqual(overridden)); 
     if (explicitIfaceImplementation) 
     { 
      return true; 
     } 

     if (IsImplicitInterfaceImplementation(method, overridden)) 
     { 
      return true; 
     } 

     // new slot method cannot override any base classes' method by convention: 
     if (method.IsNewSlot) 
     { 
      return false; 
     } 

     // check base-type overrides using Cecil's helper method GetOriginalBaseMethod() 
     return method.GetOriginalBaseMethod().IsEqual(overridden); 
    } 

    /// <summary> 
    /// Implicit interface implementations are based only on method's name and signature equivalence. 
    /// </summary> 
    private static bool IsImplicitInterfaceImplementation(MethodDefinition method, MethodReference overridden) 
    { 
     // check that the 'overridden' method is iface method and the iface is implemented by method.DeclaringType 
     if (overridden.DeclaringType.SafeResolve().IsInterface == false || 
      method.DeclaringType.Interfaces.None(i => i.IsEqual(overridden.DeclaringType))) 
     { 
      return false; 
     } 

     // check whether the type contains some other explicit implementation of the method 
     if (method.DeclaringType.Methods.SelectMany(m => m.Overrides).Any(m => m.IsEqual(overridden))) 
     { 
      // explicit implementation -> no implicit implementation possible 
      return false; 
     } 

     // now it is enough to just match the signatures and names: 
     return method.Name == overridden.Name && method.SignatureMatches(overridden); 
    } 

    static bool IsEqual(this MethodReference method1, MethodReference method2) 
    { 
     return method1.Name == method2.Name && method1.DeclaringType.IsEqual(method2.DeclaringType); 
    } 
    // IsEqual for TypeReference is similar... 
+0

¿Puede usted proporcionar por favor la falta método 'SignatureMatches'? Eso es algo complejo porque debe considerar los parámetros genéricos y los argumentos que no se pueden comparar fácilmente. – ygoe