Mono.Cecil something like Type.GetInterfaceMap?

梦想的初衷 提交于 2019-12-04 06:06:21

No, Cecil does not provide such method, because Cecil gives us just CIL metadata as they are. (There is project Cecil.Rocks, which contains some useful extension methods, but not this one)

In MSIL methods have an attribute 'overrides', which contains references to methods that this method overrides (in Cecil there is indeed a property Overrides in the MethodDefinition class). However, this attribute is used only in some special cases such as explicit interface implementation. Usually this attribute is left empty and which methods are overridden by the method in question is based on conventions. These conventions are described in ECMA CIL standard. In short a method overrides methods that have the same name and the same signature.

The following pieces of code might help you as well as this discussion: 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...
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!