Я думаю, что вы застряли при перечислении интерфейсов; Я не видел способа получить доступ к определенному интерфейсу.
Кроме того, есть небольшой крайний случай, который может произойти, если интерфейс реализован явно. В этом случае (void ISample.Do()
) MethodBase.Name будет полностью определенным именем метода (например, MyApp.ISample.Do
), а не Do
.
Единственное решение, которое я нашел, - убрать передовую информацию. Э.Г.
string methodName = input.MethodBase.Name;
int methodIndex = methodName.LastIndexOf('.');
if (methodIndex != -1)
{
methodName = methodName.Substring(methodIndex + 1,
methodName.Length - methodIndex - 1);
}
var interfaces = from i in input.MethodBase.DeclaringType.GetInterfaces()
let parameters = input.MethodBase.GetParameters().
Select(p => p.ParameterType).ToArray()
where i.GetCustomAttributes(typeof(CustomAttribute), true).Length > 0
where i.GetMethod(methodName, parameters) != null
select i;
Кроме того, если есть другой метод с таким же именем и сигнатурой, я не уверен, как определить, был ли метод вызван через интерфейс, в отличие от публичного метода.
public class Sample : ISample
{
public void Do()
{
// this is a public method
}
void ISample.Do()
{
// this is the interface implementation
}
}
Полагаю, можно было бы искать другие методы с тем же именем и сигнатурой и различать их, просматривая другие свойства MethodBase.
т.е. public void Do()
имеет IsHideBySig и IsPublic для true, в то время как void ISample.Do()
имеет IsFinal, IsVirtual, IsPrivate, IsHideBySig для всех true. Но я не уверен, что этого достаточно для всех сценариев.