How to obtain implemented Interfaces using Reflection?

G

Guest

Hi all

I'm looking for a way to obtain all interfaces implemented by a given type, i.e. all interfaces included in the type's class base specification. Sounds easy but the problem is that Type.GetInterfaces returns both inherited and implemented interfaces, including all base interfaces

The following example shows the results of Type.GetInterfaces and the results I'd like to have for various class declarations. Here {A, B} means an array of Type objects typeof(A) and typeof(B)

interface IBase {
interface IDerived: IBase {
class Base: IBase {} // GetInterfaces: {IBase} wanted: {IBase
class Derived1: Base {} // GetInterfaces: {IBase} wanted: {
class Derived2: Base, IBase {} // GetInterfaces: {IBase} wanted: {IBase
class Derived3: Base, IDerived {} // GetInterfaces: {IBase, IDerived} wanted: {IDerived
class Derived4: Base, IBase, IDerived {} // GetInterfaces: {IBase, IDerived} wanted: {IBase, IDerived

Because ildasm is able to display the list of implemented interfaces, it must be stored in metadata. But can it be retrieved using reflection? Any hints are greatly appreciated

Regards
pn
 
G

Guest

Short of listing the interfaces for both the base class and derived class and figuring out with ones they don't have in common, I know of no direct way of doing this

Charlie
 
R

Richard A. Lowe

Try this:
using System;
using System.Collections;
using System.Reflection;

namespace GetInterfacesImplementedOnly
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
writeWhatInterfacesIImplement(typeof(Base));
writeWhatInterfacesIImplement(typeof(Derived1));
writeWhatInterfacesIImplement(typeof(Derived2));
writeWhatInterfacesIImplement(typeof(Derived3));
writeWhatInterfacesIImplement(typeof(Derived4));
}

static void writeWhatInterfacesIImplement(Type type)
{
Type[] interfaces = GetBaseInterfaces(type);

string interfacesText=string.Empty;
for(int i=0;i<interfaces.Length;i++)
{
interfacesText += interfaces.Name + ",";
}

Console.WriteLine("Type {0} implements: {1}", type.Name,
interfacesText.Substring(0, interfacesText.Length-1));
}

static Type[] GetBaseInterfaces(Type type)
{
ArrayList implementedInterfaces = new ArrayList();
Type[] interfaces = type.GetInterfaces();

for(int i=0;i<interfaces.Length;i++)
{
if(type.GetInterfaceMap(interfaces).TargetType==type)
{
implementedInterfaces.Add((Type)interfaces);
}
}

if(implementedInterfaces.Count>0)
{
return (Type[])implementedInterfaces.ToArray(typeof(Type));
}
else
{
return new Type[0];
}
}
}

interface IBase {}
interface IDerived: IBase {}
class Base: IBase {} // GetInterfaces: {IBase} wanted: {IBase}
class Derived1: Base {} // GetInterfaces: {IBase} wanted: {}
class Derived2: Base, IBase {} // GetInterfaces: {IBase} wanted: {IBase}
class Derived3: Base, IDerived {} // GetInterfaces: {IBase, IDerived}
wanted: {IDerived}
class Derived4: Base, IBase, IDerived {} // GetInterfaces: {IBase,
IDerived} wanted: {IBase, IDerived}
}


--
C#, .NET and Complex Adaptive Systems:
http://blogs.geekdojo.net/Richard
pn said:
Hi all,

I'm looking for a way to obtain all interfaces implemented by a given
type, i.e. all interfaces included in the type's class base specification.
Sounds easy but the problem is that Type.GetInterfaces returns both
inherited and implemented interfaces, including all base interfaces.
The following example shows the results of Type.GetInterfaces and the
results I'd like to have for various class declarations. Here {A, B} means
an array of Type objects typeof(A) and typeof(B).
interface IBase {}
interface IDerived: IBase {}
class Base: IBase {} // GetInterfaces: {IBase} wanted: {IBase}
class Derived1: Base {} // GetInterfaces: {IBase} wanted: {}
class Derived2: Base, IBase {} // GetInterfaces: {IBase} wanted: {IBase}
class Derived3: Base, IDerived {} // GetInterfaces: {IBase, IDerived} wanted: {IDerived}
class Derived4: Base, IBase, IDerived {} // GetInterfaces: {IBase,
IDerived} wanted: {IBase, IDerived}
Because ildasm is able to display the list of implemented interfaces, it
must be stored in metadata. But can it be retrieved using reflection? Any
hints are greatly appreciated.
 
G

Guest

From what I understand, you're suggesting to take the interfaces returned from derivedClass.GetInterfaces and remove all interfaces returned from baseClass.GetInterfaces. Unfortunately, this doesn't give the correct results

interface I {
class Base: I {
class Derived1: Base {} // wanted: {} your result: {
class Derived2: Base, I {} // wanted: {I} your result: {}
 
G

Guest

I appreciate your efforts, but have you ever run your program? Its output is exactly the same as calling Type.GetInterfaces for all five classes

Regards
pn
 
R

Richard A. Lowe

D'oh! Yes, you're right - I -think- you could infer it if you change the
line in the GetBaseInterfaces() method to:

if(type.GetInterfaceMap(interfaces).InterfaceMethods[0].DeclaringType==ty
pe)

but that will only work if you have members in your interface and the first
one maps to the declaring type.
--
C#, .NET and Complex Adaptive Systems:
http://blogs.geekdojo.net/Richard
pn said:
I appreciate your efforts, but have you ever run your program? Its output
is exactly the same as calling Type.GetInterfaces for all five classes.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top