WindowsDevCenter.com
oreilly.comSafari Books Online.Conferences.

advertisement


AddThis Social Bookmark Button

Programming C#: Attributes and Reflection
Pages: 1, 2, 3, 4, 5, 6, 7, 8, 9

Type Discovery

You can use reflection to explore and examine the contents of an assembly. You can find the types associated with a module; the methods, fields, properties, and events associated with a type, as well as the signatures of each of the type's methods; the interfaces supported by the type; and the type's base class.

To start, load an assembly dynamically with the Assembly.Load static method. The Assembly class encapsulates the actual assembly itself, for purposes of reflection. The signature for the Load method is:

public static Assembly.Load(AssemblyName)

For the next example, pass in the Core Library to the Load method. MsCorLib.dll has the core classes of the .NET Framework:

Assembly a = Assembly.Load("Mscorlib.dll");

Once the assembly is loaded, you can call GetTypes( ) to return an array of Type objects. The Type object is the heart of reflection. Type represents type declarations: classes, interfaces, arrays, values, and enumerations:

Type[] types = a.GetTypes( );

The assembly returns an array of types that you can display in a foreach loop, as shown in Example 18-3. Because this listing uses the Type class, you will want to add a using statement for the System.Reflection namespace.


Example 18-3: Reflecting on an assembly

namespace Programming_CSharp
{
  using System;
  using System.Reflection;
 
  public class Tester
  {
    public static void Main( )
    {
      // what is in the assembly
      Assembly a = Assembly.Load("Mscorlib.dll");
      Type[] types = a.GetTypes( );
      foreach(Type t in types)
      {
          Console.WriteLine("Type is {0}", t);
      }
      Console.WriteLine(
        "{0} types found", types.Length);
    }
  }
}

The output from this would fill many pages. Here is a short excerpt:

Type is System.TypeCode
Type is System.Security.Util.StringExpressionSet
Type is System.Runtime.InteropServices.COMException
Type is System.Runtime.InteropServices.SEHException
Type is System.Reflection.TargetParameterCountException
Type is System.Text.UTF7Encoding
Type is System.Text.UTF7Encoding$Decoder
Type is System.Text.UTF7Encoding$Encoder
Type is System.ArgIterator
Type is System.Runtime.Remoting.JITLookupTable
Type is System.Runtime.Remoting.IComponentServices
Type is System.Runtime.Remoting.ComponentServices
1429 types found

This example obtained an array filled with the types from the Core Library and printed them one by one. The array contained 1,429 entries on my machine.

Reflecting on a Type

You can reflect on a single type in the mscorlib assembly as well. To do so, you extract a type from the assembly with the GetType( ) method, as shown in Example 18-4.


Example 18-4: Reflecting on a type

namespace Programming_CSharp
{
  using System;
  using System.Reflection;
 
  public class Tester
  {
    public static void Main( )
    {
      // examine a single object
       Type theType =
        Type.GetType(
          "System.Reflection.Assembly");
       Console.WriteLine(
        "\nSingle Type is {0}\n", theType);
    }
  }  
}

Output:

Single Type is System.Reflection.Assembly


Finding all type members

You can ask the Assembly type for all its members using the GetMembers( ) method of the Type class, which lists all the methods, properties, and fields, as shown in Example 18-5.

Example 18-5: Reflecting on the members of a type

namespace Programming_CSharp
{
  using System;
  using System.Reflection;
 
  public class Tester
  {
   public static void Main( )
   {
     // examine a single object
     Type theType =
      Type.GetType(
        "System.Reflection.Assembly");
     Console.WriteLine(
      "\nSingle Type is {0}\n", theType);
 
     // get all the members
     MemberInfo[] mbrInfoArray =
      theType.GetMembers( );
     foreach (MemberInfo mbrInfo in mbrInfoArray )
     {
      Console.WriteLine("{0} is a {1}",
        mbrInfo, mbrInfo.MemberType);
     }
   }
  }  
}

Once again the output is quite lengthy, but within the output you see fields, methods, constructors, and properties, as shown in this excerpt:

System.String s_localFilePrefix is a Field
Boolean IsDefined(System.Type) is a Method
Void .ctor(  ) is a Constructor
System.String CodeBase  is a Property
System.String CopiedCodeBase  is a Property

Finding type methods

You might want to focus on methods only, excluding the fields, properties, and so forth. To do so, you remove the call to GetMembers( ):

MemberInfo[] mbrInfoArray = 
    theType.GetMembers(BindingFlags.LookupAll);

and add a call to GetMethods( ):

mbrInfoArray = theType.GetMethods(  );

The output now is nothing but the methods:

Output (excerpt):

Boolean Equals(System.Object) is a Method
System.String ToString(  ) is a Method
System.String CreateQualifiedName(
      System.String, System.String) is a Method
System.Reflection.MethodInfo get_EntryPoint(  ) is a Method

Finding particular type members

Finally, to narrow it down even further, you can use the FindMembers method to find particular members of the type. For example, you can narrow your search to methods whose names begin with the letters Get.

To narrow the search, you use the FindMembers method, which takes four parameters: MemberTypes, BindingFlags, MemberFilter, and object.

MemberTypes
A MemberTypes object that indicates the type of the member to search for. These include All, Constructor, Custom, Event, Field, Method, Nestedtype, Property, and TypeInfo. You will also use the MemberTypes.Method to find a method.
BindingFlags
An enumeration that controls the way searches are conducted by reflection. There are a great many BindingFlag values, including IgnoreCase, Instance, Public, Static, and so forth. The BindingFlags default member indicates no binding flag, which is what you want because you do not want to restrict the binding.
MemberFilter
A delegate (see Chapter 12) that is used to filter the list of members in the MemberInfo array of objects. The filter you'll use is Type.FilterName, a field of the Type class used for filtering on a name.
Object
A string value that will be used by the filter. In this case you'll pass in "Get*" to match only those methods that begin with the letters Get.

The complete listing for filtering on these methods is shown in Example 18-6.


Example 18-6: Finding particular members

namespace Programming_CSharp
{
  using System;
  using System.Reflection;
 
  public class Tester
  {
   public static void Main( )
   {
     // examine a single object
     Type theType = Type.GetType(
      "System.Reflection.Assembly");
 
     // just members which are methods beginning with Get
     MemberInfo[] mbrInfoArray =
      theType.FindMembers(MemberTypes.Method,
        BindingFlags.Default,
        Type.FilterName, "Get*");
     foreach (MemberInfo mbrInfo in mbrInfoArray )
     {
      Console.WriteLine("{0} is a {1}",
        mbrInfo, mbrInfo.MemberType);
     }
   }
  }

Output (excerpt):

System.Type[] GetTypes(  ) is a Method
System.Type[] GetExportedTypes(  ) is a Method
System.Type GetType(System.String, Boolean) is a Method
System.Type GetType(System.String) is a Method
System.Reflection.AssemblyName GetName(Boolean) is a Method
System.Reflection.AssemblyName GetName(  ) is a Method
Int32 GetHashCode(  ) is a Method

Pages: 1, 2, 3, 4, 5, 6, 7, 8, 9

Next Pagearrow