我有一个界面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;
}