Посмотрим.Насколько я знаю, нет никакого способа BCL только получить интерфейсы, которые фактически реализованы для определенного типа, но исключают любые интерфейсы, которые наследуются этим типом.Таким образом, нам придется бросить наше собственное:
public static Dictionary<Type, IEnumerable<Type>> GetInterfaceHierarchyMap(this Type type)
{
List<Type> typeAncestry = new List<Type>();
Type ancestor = type;
while(ancestor != null)
{
typeAncestry.Add(ancestor);
ancestor = ancestor.BaseType;
}
Dictionary<Type, IEnumerable<Type>> interfaceMaps = new Dictionary<Type, IEnumerable<Type>>();
foreach(Type childType in typeAncestry.Reverse<Type>())
{
var mappedInterfaces = interfaceMaps.SelectMany(kvp => kvp.Value);
var allInterfacesToPoint = childType.GetInterfaces();
interfaceMaps.Add(childType, allInterfacesToPoint.Except(mappedInterfaces));
}
return interfaceMaps;
}
Один шаг за раз:
- Мы начинаем с текущего типа и поднимаемся по BaseType пока мы не достигнем корневого типа.
- Мы переворачиваем список, поэтому, когда мы перебираем его, мы сначала начинаем с корневого типа.
- Для каждого типа вниз по цепочке мы получаем все интерфейсыприменяется к этому типу и наследуется от типов-предков, затем мы используем Кроме , чтобы исключить все те, которые мы уже нашли в предыдущих итерациях.
Это будет рассматривать дублированные требования интерфейса как излишние -т. е. если один из ваших типов-предков реализует IDisposable, а ваш тип - тоже, будет учитываться только самая ранняя реализация.
Гипотетическим результатом этого метода будет словарь, который выглядит примерно так:
[object] - []
[BaseBaseClass] - [ISomeInterface]
[BaseClass] - [IAnotherInterface, IOneMore]
[ConcreteClass] - [IYetAnother]