2011-02-07 2 views

ответ

7

Нет, Сесил не предоставляет такой метод, потому что Сесил дает нам только метаданные CIL, как они есть. (Существует проект Cecil.Rocks, который содержит некоторые полезные методы расширения, но не этот)

В методах MSIL атрибут «переопределяет», который содержит ссылки на методы, которые этот метод переопределяет (в Сесиле действительно есть свойство Переопределяет класс MethodDefinition). Однако этот атрибут используется только в некоторых особых случаях, таких как реализация явного интерфейса. Обычно этот атрибут остается пустым и какие методы переопределяются рассматриваемым методом, основывается на соглашениях. Эти соглашения описаны в стандарте ECMA CIL. Короче говоря, метод переопределяет методы, имеющие одно и то же имя и одну и ту же подпись.

Следующие фрагменты кода может помочь вам, а также дискуссии: 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

Можете ли вы предоставить недостающую 'метод SignatureMatches'? Это сложная вещь, потому что она должна учитывать общие параметры и аргументы, которые невозможно легко сравнить. – ygoe

Смежные вопросы