如何根据具体实现的MethodInfo获取接口Methodinfo?

时间:2017-08-25 11:36:00

标签: c# .net reflection interface attributes

我有一个界面IClass

public interface IClass
{
    [MyAttribute]
    void Hello();

    [MyAttribute]
    void Farewell();
}

实施Class1

public class Class1 : IClass
{
    public void Hello() { Console.WriteLine("Hi there") };

    void IClass.Farewell() { Console.WriteLine("Goodbye!") };
}

我通过拦截来Class1 MethodInfo Hello()IClass.Farewell()处理,但我需要找到 interface 定义的MethodInfo,以便发现属性MyAttribute的用法;像这样的东西:

MethodInfo mi = context.Descriptior.CurrentMethod;
MethodInfo imi = GetInterfaceMethodInfo(mi) // ???
var mas = GetCustomAttributes<MyAttribute>();
if (mas.Count > 0)
{
    // Profit!
}

修改

我可能未能正确强调的一点:我从拦截器获取了初始MethodInfo实例,因此我不仅试图找到界面的方法,但是我需要确定是否有一个接口正在播放,如果是这样,我需要找到与被调用方法相对应的方法声明。

我有一个解决方法,涵盖了我目前的情况。从好的方面来看:它有效。缺点:它使用字符串比较,我发现它本身就是假定的。

    private bool HasAttribute(MethodInfo methodInfo)
    {
        var type = methodInfo.DeclaringType;

        var interfaces = type.GetInterfaces();

        foreach (var @interface in interfaces)
        {
            var iMethodInfo = @interface.GetMethods()
                .SingleOrDefault(x =>
                    (
                        methodInfo.Name.EndsWith($".{@interface.Name}.{x.Name}") || methodInfo.Name.Equals(x.Name)
                    )
                    && IsSignatureMatch(x, methodInfo)
                );

            if (iMethodInfo != null)
            {
                Console.WriteLine(iMethodInfo.Name);

                if (iMethodInfo.GetCustomAttribute<MyAttribute>() != null)
                {
                    return true;
                }
            }
        }

        return false;
    }

    private bool IsSignatureMatch(MethodInfo methodInfoA, MethodInfo methodInfoB)
    {
        if (methodInfoA.ReturnType != methodInfoB.ReturnType)
        {
            return false;
        }

        var a = methodInfoA.GetParameters().Select(x => x.ParameterType).ToList();
        var b = methodInfoB.GetParameters().Select(x => x.ParameterType).ToList();

        if (a.Count != b.Count)
        {
            return false;
        }

        for (var i = 0; i < a.Count; i++)
        {
            if (a[i] != b[i])
            {
                return false;
            }
        }

        return true;
    }

0 个答案:

没有答案