- Reflection on Types
- Getting Started with C# Reflection
- More Advanced Uses of C# Reflection
- Reflection and Loose Coupling: Late Binding
- Conclusion
Getting Started with C# Reflection
To get a feel for the types of things you can do with C# reflection, look at the simple class definition in Listing 1.
Listing 1A simple class.
public class Person { public Person(String name) { this.name = name; } public String name; public string Name { get { return name; } } }
As perhaps the simplest possible example of the use of reflection, Listing 2 illustrates an object of this class and a call into the C# reflection services.
Listing 2Getting the type of an object.
Person person = new Person("Stephen"); Console.WriteLine("Person class type: {0}", person.GetType());
The code in Listing 2 produces the following output:
Person class type: ReflectionConsoleApplication.Person
Nothing too exciting there—we've simply discovered the parent class for the person object. Let's make things a little more interesting by introducing another class with some interfaces, as shown in Listing 3.
Listing 3A new class with two interfaces.
public interface IMyBaseInterface { void DoSomethingBasic(); } public interface IMyInterface : IMyBaseInterface { void DoSomethingOrOther(); } class AncillaryClass : IMyInterface { public void DoSomethingOrOther() { Console.WriteLine("Now doing something"); } public void DoSomethingBasic() { Console.WriteLine("Now doing something basic"); } }
In Listing 3, I have a base interface called IMyBaseInterface. I also have an interface called IMyInterface that inherits the base interface. In addition, I have a class that implements the IMyInterface interface.
This structure gives us a simple interface-based inheritance hierarchy. Let's play around with this code using reflection, as in Listing 4.
Listing 4Reflecting over the new class.
AncillaryClass ancillary = new AncillaryClass(); Console.WriteLine("AncillaryClass type: {0}", ancillary.GetType()); IMyBaseInterface iMyBaseInterface; iMyBaseInterface = ancillary; Console.WriteLine("iMyBaseInterface type: {0}", iMyBaseInterface.GetType()); Console.WriteLine("iMyBaseInterface.GetType().IsClass: {0}", iMyBaseInterface.GetType().IsClass);
The code in Listing 4 produces the following program output:
AncillaryClass type: ReflectionConsoleApplication.AncillaryClass iMyBaseInterface type: ReflectionConsoleApplication.AncillaryClass iMyBaseInterface.GetType().IsClass: True
In the second line of Listing 4, notice the use of what's called interface-based polymorphism; I've assigned an object of AncillaryClass to the instance of IMyBaseInterface. Then, when I get the type of the interface object, it has a type of AncillaryClass. This is an example of interface-based polymorphism where I appear to change the type of an instance variable. Perhaps more surprising is the fact that the underlying type of this interface object is now that of a class, as indicated by the call to iMyBaseInterface.GetType().IsClass. How can an interface now be a class?
This makes sense when you realize that a C# interface is simply a placeholder for code that must be implemented by an inheriting class. So you can use interface-based polymorphism to manipulate the underlying type.
Now let's get a little more ambitious! Say we want to use reflection to look a little more deeply inside a given object; for example, to see what methods a given object supports. We can do this using the code in Listing 5.
Listing 5Extracting method details.
MethodInfo[] methodInfo = ancillary.GetType().GetMethods(); foreach (MethodInfo m in methodInfo) Console.WriteLine("Method name: {0}", m.Name);
The output from Listing 5 looks something like Listing 6.
Listing 6The extracted object methods.
Method name: DoSomethingOrOther Method name: DoSomethingBasic Method name: ToString Method name: Equals Method name: GetHashCode Method name: GetType
Comparing Listing 6 with Listing 3, we see that the object of interest (ancillary) has two programmer-supplied methods (DoSomethingOrOther and DoSomethingBasic) and four other system-supplied methods.