acidzombie24 acidzombie24 - 9 months ago 31
C# Question

Get only direct interface instead of all?

I have a class like the below. GetInterfaces() says

If the current Type represents a type
parameter in the definition of a
generic type or generic method, this
method searches the interface
constraints and any interfaces
inherited from class or interface

Is it possible for me to not get any inherited interface? When i use GetInterfaces on ABC i only want to see DEF, not DEF and GHI.

interface DEF : GHI {...}
class ABC : DEF {...}

Ani Ani

Firstly, the MSDN snippet you've posted doesn't have anything to do with your actual question. It deals with when you have, for example, a generic type such as class Foo<T> where T : IEnumerable, and you try calling GetInterfaces on the type-parameter T, for example through typeof(Foo<>).GetGenericArguments().Single().GetInterfaces().

Secondly, the problem is slightly ill-specified. Note that when a class implements an interface, it must implement all of the interfaces 'inherited' by that interface. It's simply a C# convenience feature that lets you omit the inherited interfaces in the class-declaration. In your example, it's perfectly legal (and no different) to explicitly include the 'inherited' GHI interface:

class ABC : DEF, GHI {...}

I've assumed that what you really want to do is find a 'minimal set' of interfaces that 'covers' all of the type's implemented interfaces. This results in a slightly simplified version of the Set cover problem.

Here's one way to solve it, without any attempt whatsoever to be algorithmically efficient. The idea is to produce the minimal interface-set by filtering out those interfaces that are already implemented by other interfaces implemented by the type.

Type type = ...

var allInterfaces = type.GetInterfaces();    
var minimalInterfaces = from iType in allInterfaces 
                        where !allInterfaces.Any(t => t.GetInterfaces()
                        select iType;

( EDIT - Here's a better way of doing the above:

var minimalInterfaces = allInterfaces.Except
                        (allInterfaces.SelectMany(t => t.GetInterfaces()));


For example, for List<int>:





Do note that this solution covers interface 'hierarchies' only (which is what you appear to want), not how they relate to the class's class hierarchy. In particular, it pays no attention to where in a class's hierarchy an interface was first implemented.

For example, let's say we have:

interface IFoo { }
interface IBar : IFoo { }
interface IBaz { } 

class Base : IBar {  }
class Derived : Base, IBaz {  }

Now if you try using the solution I've described to get the minimal interface-set for Derived, you would get IBaz as well as IBar. If you don't want IBar, you would have to go to more effort: eliminate interfaces implemented by base-classes. The easiest way to do this would be to remove from the minimal interface-set those interfaces implemented by the class's immediate base-class, as is mentioned in @MikeEast's answer.