BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

Reflection
.NET 1.1+

Reflecting Implemented Interface Information

The eleventh part of the Reflection tutorial describes the techniques for examining a type and determining which interfaces, if any, it implements. The processes can be used to find implemented interfaces for classes, structures and other interfaces.

Implemented Interfaces

A key part of polymorphism is the implementation of interfaces, allowing objects of different types to be interchanged as long as they share an interface. Using reflection you can interrogate a type to determine which interfaces it implements and use this information for various purposes. For example, you can instantiate an object and cast it to that interface using techniques including late binding. We will look at this later in the tutorial. In this instalment we'll concentrate on obtaining information about the interfaces that a specific type implements. The processes described will work with the sample code shown below. Each example will reflect information about a class. However, the methods that we use can equally be applied to structures and interfaces too.

The sample class represents a Mars Lander robot and has several methods. These methods are defined in the IPlanetaryLander interface, which the MarsLander class implements directly, and the IMoveable and IDisposable interfaces, which are inherited via the IPlanetaryLander interface.

public interface IMoveable
{
    void Rotate(int clockWiseDegrees);
    void MoveForward(int distance);
}


public interface IPlanetaryLander : IMoveable, IDisposable
{
    void TakeSample();
}


public class MarsLander : IPlanetaryLander
{
    public void TakeSample() { /* Code omitted */ }
    public void Rotate(int clockWiseDegrees) { /* Code omitted */ }
    public void MoveForward(int distance) { /* Code omitted */ }
    public void Dispose() { /* Code omitted */ }
}

The types and methods we will use are in the System.Reflection namespace, so ensure your code includes the following using directive:

using System.Reflection;

Obtaining a Single Implemented Interface of a Type

If you have been following the entire tutorial you will have spotted a pattern to the way in which information is reflected. Extracting interface information for a type follows the same pattern, with methods to obtain either a single, named interface or a group of implemented interfaces. We'll start with the former.

The Type class' GetInterface method has two overloaded versions. The first accepts a string argument that contains the name of the interface for which you wish to obtain information. This is a case-sensitive string. If the class being examined implements the named interface, a Type object representing that interface is returned. If the interface is not known, the method returns null.

We can try out the method using the code below. Here we create a Type object for MarsLander and then use reflection to create a Type instance for its IPlanetaryLander interface. Finally we output the Name property for the interface. I won't describe the other properties that the Type class provides as these have been covered earlier in the tutorial.

Type type = typeof(MarsLander);
Type iface = type.GetInterface("IPlanetaryLander");
Console.WriteLine(iface.Name);          // IPlanetaryLander

The list of interfaces that can be obtained for a type include those that are implemented directly and those defined in interfaces higher in the type hierarchy. For example, we can get details of the IMoveable interface, which is included in the MarsLander class via the IPlanetaryLander type.

Type type = typeof(MarsLander);
Type iface = type.GetInterface("IMoveable");
Console.WriteLine(iface.Name);          // IMoveable

In some cases you will want to perform a case-insensitive search for an interface. This is particularly useful if the interface name is to be provided by a user. An overloaded version of the GetInterface method includes a second, Boolean parameter that controls case-sensitivity. Setting this value to true makes the search ignore the case of the letters in the interface name. If set to false, the search remains case-sensitive.

Type type = typeof(MarsLander);
Type iface = type.GetInterface("imoveable", true);
Console.WriteLine(iface.Name);          // IMoveable

Obtaining All Implemented Interfaces of a Type

When you want to obtain details of all of the interfaces that a particular type implements, you can use the GetInterfaces method of the Type class. This retrieves an array of Type objects, with one element per interface. Again, the method returns both interfaces that are implemented directly by the class and those implemented higher in the type hierarchy. There are no overloaded versions of the method.

Type type = typeof(MarsLander);
Type[] ifaces = type.GetInterfaces();

foreach (Type iface in ifaces)
{
    Console.WriteLine(iface.Name);
}

/* OUTPUT

IPlanetaryLander
IMoveable
IDisposable

*/
8 May 2012