Free mag vol1 | Page 622

CHAPTER 15  TYPE REFLECTION, LATE BINDING, AND ATTRIBUTE-BASED PROGRAMMING Building a Custom Metadata Viewer To illustrate the basic process of reflection (and the usefulness of System.Type), let’s create a Console Application named MyTypeViewer. This program will display details of the methods, properties, fields, and supported interfaces (in addition to some other points of interest) for any type within mscorlib.dll (recall all .NET applications have automatic access to this core framework class library) or a type within MyTypeViewer itself. Once the application has been created, be sure to import the System.Reflection namespace. // Need to import this namespace to do any reflection! using System.Reflection; Reflecting on Methods The Program class will be updated to define a number of static methods, each of which takes a single System.Type parameter and returns void. First you have ListMethods(), which (as you might guess) prints the name of each method defined by the incoming type. Notice how Type.GetMethods() returns an array of System.Reflection.MethodInfo objects, which can be enumerated over using a standard foreach loop, as follows: // Display method names of type. static void ListMethods(Type t) { Console.WriteLine("***** Methods *****"); MethodInfo[] mi = t.GetMethods(); foreach(MethodInfo m in mi) Console.WriteLine("->{0}", m.Name); Console.WriteLine(); } Here, you are simply printing the name of the method using the MethodInfo.Name property. As you might guess, MethodInfo has many additional members that allow you to determine whether the method is static, virtual, generic, or abstract. As well, the MethodInfo type allows you to obtain the method’s return value and parameter set. You’ll spruce up the implementation of ListMethods() in just a bit. If you wish, you could also build a fitting LINQ query to enumerate the names of each method. Recall from Chapter 12, LINQ to Objects allows you to build strongly typed queries that can be applied to in-memory object collections. As a good rule of thumb, whenever you find blocks of looping or decision programming logic, you could make use of a related LINQ query. For example, you could rewrite the previous method as so: static void ListMethods(Type t) { Console.WriteLine("***** Methods *****"); var methodNames = from n in t.GetMethods() select n.Name; foreach (var name in methodNames) Console.WriteLine("->{0}", name); Console.WriteLine(); } 564