Во-первых, размещенный вами фрагмент MSDN не имеет никакого отношения к вашему актуальному вопросу. Он имеет дело, когда у вас есть, например, универсальный тип, такой как class Foo<T> where T : IEnumerable
, и вы пытаетесь вызвать GetInterfaces
для параметра типа T
, например, через typeof(Foo<>).GetGenericArguments().Single().GetInterfaces().
Во-вторых, проблема слегка плохо определена. Обратите внимание, что когда класс реализует интерфейс, он должен реализовать все интерфейсов, «унаследованных» этим интерфейсом. Это просто удобная функция C #, которая позволяет опустить унаследованные интерфейсы в объявлении класса. В вашем примере это совершенно законно (и ничем не отличается) от явно , включая «унаследованный» интерфейс GHI
:
class ABC : DEF, GHI {...}
Я предположил, что вы действительно хотите найти «минимальный набор» интерфейсов, который «охватывает» все реализованные интерфейсы типа. Это приводит к несколько упрощенной версии проблемы Set cover .
Вот один из способов ее решения, без какой-либо попытки быть алгоритмически эффективным. Идея состоит в том, чтобы создать минимальный набор интерфейсов, отфильтровывая те интерфейсы, которые уже реализованы с помощью других интерфейсов, реализованных типом.
Type type = ...
var allInterfaces = type.GetInterfaces();
var minimalInterfaces = from iType in allInterfaces
where !allInterfaces.Any(t => t.GetInterfaces()
.Contains(iType))
select iType;
(
РЕДАКТИРОВАТЬ - Вот лучший способ сделать выше:
var minimalInterfaces = allInterfaces.Except
(allInterfaces.SelectMany(t => t.GetInterfaces()));
)
Например, для List<int>
:
allInterfaces:
System.Collections.Generic.IList`1[System.Int32]
System.Collections.Generic.ICollection`1[System.Int32]
System.Collections.Generic.IEnumerable`1[System.Int32]
System.Collections.IEnumerable
System.Collections.IList
System.Collections.ICollection
minimalInterfaces:
System.Collections.Generic.IList`1[System.Int32]
System.Collections.IList
Обратите внимание, что это решение охватывает только интерфейс «иерархий» (а это то, что вам нужно), а не то, как они связаны с иерархией class класса. В частности, он не обращает внимания на , где в иерархии классов интерфейс был впервые реализован.
Например, скажем, у нас есть:
interface IFoo { }
interface IBar : IFoo { }
interface IBaz { }
class Base : IBar { }
class Derived : Base, IBaz { }
Теперь, если вы попытаетесь использовать решение, которое я описал, чтобы получить минимальный набор интерфейсов для Derived
, вы получите IBaz
, а также IBar
. Если вы не хотите IBar
, вам придется приложить больше усилий: устранить интерфейсы, реализованные базовыми классами. Самый простой способ сделать это - удалить из минимального набора интерфейсов те интерфейсы, которые реализованы непосредственным базовым классом класса, как упомянуто в ответе @ MikeEast.