Ответ 1
Во-первых, фрагмент MSDN, который вы опубликовали, не имеет никакого отношения к вашему фактическому вопросу. Он имеет дело с тем, что у вас есть, например, общий тип, например class Foo<T> where T : IEnumerable
, и вы пытаетесь вызвать GetInterfaces
для параметра типа T
, например, через typeof(Foo<>).GetGenericArguments().Single().GetInterfaces().
Во-вторых, проблема слегка не указана. Обратите внимание: когда класс реализует интерфейс, он должен реализовать все наследуемые интерфейсы этого интерфейса. Это просто удобная функция С#, которая позволяет опускать наследуемые интерфейсы в декларации класса. В вашем примере он совершенно легален (и не отличается), чтобы явно включать интерфейс "унаследованный" GHI
:
class ABC : DEF, GHI {...}
Я предположил, что вы действительно хотите найти "минимальный набор" интерфейсов, который "покрывает" все интерфейсы, реализованные на типе. Это приводит к слегка упрощенной версии Задайте проблему обложки.
Здесь один из способов его решения, без какой-либо попытки быть алгоритмически эффективным. Идея состоит в том, чтобы создать минимальный набор интерфейсов, отфильтровывая те интерфейсы, которые уже реализованы другими интерфейсами, реализованными типом.
Type type = ...
var allInterfaces = type.GetInterfaces();
var minimalInterfaces = from iType in allInterfaces
where !allInterfaces.Any(t => t.GetInterfaces()
.Contains(iType))
select iType;
( EDIT. Здесь лучший способ сделать это:
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
Обратите внимание, что это решение охватывает только иерархии интерфейсов (что вам кажется нужным), а не то, как они относятся к иерархии классов классов. В частности, он не обращает внимания на то, где в иерархии классов сначала был реализован интерфейс.
Например, допустим, что мы имеем:
interface IFoo { }
interface IBar : IFoo { }
interface IBaz { }
class Base : IBar { }
class Derived : Base, IBaz { }
Теперь, если вы попытаетесь использовать решение, которое я описал, чтобы получить минимальный набор интерфейсов для Derived
, вы получите IBaz
, а также IBar
. Если вы не хотите IBar
, вам нужно будет приложить больше усилий: устранить интерфейсы, реализуемые базовыми классами. Самый простой способ сделать это - удалить из минимального интерфейса - установить те интерфейсы, которые реализуются классом немедленного базового класса, как указано в ответе @MikeEast.