首先,为了强调XY问题的可能性,我将指出我的主要目标是确定IInvocation是否包含某个属性。
为此,我需要获取IInvocation的派生方法的MethodInfo。
为此,我需要将IInvocation的接口MethodInfo的方法签名与IInvocation的派生类型中的所有方法的签名进行比较。
为此,I need to check 'kind (value, reference, or output)' of parameters。
如何?
我的代码(请注意待办事项):
internal bool DoesInvocationContainAttribute<T>(IInvocation invocation) where T : Attribute
{
var request = invocation.Request;
var interfaceMethod = request.Method;
var interfaceType = interfaceMethod.DeclaringType;
var derivedType = request.Target.GetType();
var derivedMethod = GetDerivedMethod(derivedType, interfaceMethod);
return
derivedType.HasAttribute<T>()
|| (interfaceType?.HasAttribute<T>() ?? false)
|| derivedMethod.HasAttribute<T>()
|| interfaceMethod.HasAttribute<T>();
}
private static MethodInfo GetDerivedMethod(Type derivedType, MethodInfo interfaceMethod)
=> derivedType.GetMethods().Single(
derivedMethod => derivedMethod.Name == interfaceMethod.Name
&& AreParamsEqualForOverloadResolution(derivedMethod.GetParameters(), interfaceMethod.GetParameters()));
private static bool AreParamsEqualForOverloadResolution(
IEnumerable<ParameterInfo> paramsA, IEnumerable<ParameterInfo> paramsB)
{
var requiredParamsA = paramsA.Where(p => !p.IsOptional).OrderBy(p => p.Position).ToList();
var requiredParamsB = paramsB.Where(p => !p.IsOptional).OrderBy(p => p.Position).ToList();
if (requiredParamsA.Count != requiredParamsB.Count) return false;
for (var i = 0; i < requiredParamsA.Count; i++)
{
var paramA = requiredParamsA[i];
var paramB = requiredParamsB[i];
if (paramA.ParameterType != paramB.ParameterType) return false;
//TODO How do I determine type?
}
return true;
}
也(不确定是否应该将其作为一个单独的问题),是否有比自己编写的方法更简洁的方法-理想情况下是.Net中的某种内容,以便Microsoft出于某种原因决定更改构成以下内容的内容:方法签名,我可以升级而不必更改代码?