Published: 20 Oct 2010
By: Xianzhong Zhu
Download Sample Code

As introduced in the first article, the most typically-used tools associated with .NET reflection are: the Type class and Assembly class related members. In this second article, we are going to pick up the .NET reflection tools to set up more samples to explore the wide and extensive use of reflection.

Contents [hide]

The C# 4.0 Reflection Programming series

  • Part 1 An introduction to Reflection in C#.
  • Part 2 As introduced in the first article, the most typically-used tools associated with .NET reflection are: the Type class and Assembly class related members. In this second article, we are going to pick up the .NET reflection tools to set up more samples to explore the wide and extensive use of reflection.
  • Part 3 In the previous article, we used the reflection to obtain the information of an assembly, module, type, and type members. In this article, we'll turn to discuss another important aspect related to reflection-Attribute programming. We are going to first look at the mostly-used .NET built-in Attributes, and then try to write a custom Attribute. At last, we'll rest upon reflection to acquire the custom attribute info.
  • Part 4 In this last article of this series, we will learn what to do with reflection. But before making the topic more interesting, we'll first look at how to dynamically create an object.
  • Reflect Basic Types

    Here, reflecting the "basic types" is relative to the generic types because reflecting the generic types will be more complex. In the examples given in the first article, we are able to get all types inside an assembly, as well as print them. As a matter of fact, the output results only list the type's full name. In real cases, we often need more detailed information about the types. In this section, we will continue to see how to obtain the type related information.

    Note because an assembly contains many types, one type contains a lot of members (methods, properties, etc.), and one member also contains a lot of other information, if we write assembly-level code to obtain information on each level, then many nested foreach statements will be used. To ease reading, I will remove the outermost loop.

    Obtain Basic Information

    With the introduction of the Type class above, we can directly write the code - if necessary, notes will be provided. In this case, we will write another method named TypeExplore, used to obtain detailed information of the specified type (remember the previous AssemblyExplore method only obtain the names of the types?).

    Listing 1: Obtain detailed information of the specified type

    Now, let's invoke the above method in the Main method:

    Here, by using the C# typeof operator, we acquire an instance of Type of the DemoClass type defined in our custom assemble Demo.dll. Figure 1 indicates the running-time output result.

    Figure 1: Dump the detailed info of the class DemoClass

    Dump the detailed info of the class DemoClass

    It is worth noting the Attributes property returns a bit tag - TypeAttributes, which identify some of the meta-information of the type. Inside it, you can see our familiar flags, such as Class, Public, Sealed, etc. Accordingly, the properties, such as IsClass, IsSealed, IsPublic, also return true.

    Member Information and the MemberInfo Type

    Let us first consider a question: for the type Type, what types may it contain? The commonly-seen types include fields, properties, methods, constructors, interfaces, and nested types. The MemberInfo class represents the member type of Type. It is worth noting that class Type itself is inherited from the MemberInfo class. This is not difficult to understand because a type is often the member of another type. Class Type provides a few methods, such as GetMembers(), GetMember(), FindMember(), etc. to obtain a specified member type.

    Now, let's create a new method MemberExplore(), with which to watch all type members of a specified type.

    Listing 2: Acquire all the member info of specified type

    Then, let's put the above method invocation inside the Main method.

    The output result is shown in Figure 2.

    Figure 2: Output all the member info of the custom class DemoClass

    Output all the member info of the custom class DemoClass

    In the above case, we used the GetMembers() method to get an array of the members information, and then traversed the array, outputting the name and type of members. As we've known, After the compilation is over, the Name property turns into two independent methods - get_Name() and set_Name(); the registration operator (=) and registration cancellation operator (-=) of the myEvent event become the add_myEvent() and remove_myEvent() methods, respectively. At the same time, we found that the private field name not be printed. At last, the two members, GetType() and Equals(), of the base class System.Object is also printed out.

    Sometimes we may not want to see the base class members, while at other times we may also want to obtain the private members. In these cases, you can use the overloaded versions of the GetMembers() method, with the bit flags BindingFlags passed as parameter. BindingFlags is used to decide how to get members (and can also control how to create object instances, described later on). For this example, if we want to get all of the public, private, static, and instance members, we only need to modify the GetMembers() method like this.

    Listing 3: A new version to call the GetMembers() method

    Using the new version to call the GetMembers() method, we can get the output, as shown in Figure 3.

    Figure 3: The new output related to the new GetMembers() method invocation

    The new output related to the new GetMembers() method invocation

    You can see that, methods inherited from the base class System.Object have been filtered out; at the same time, the private fields, such as name, myEvent and so on, have all been dumped out.

    Now, if we want to get all the methods, we can use the FindMembers() method of class Type, as follows:

    The above Type.FilterName returns an instance of the MemberFilter type, which indicates to filter according to the method name. The last argument "*" indicates to return all the names (if you use "Get*", it will return all the methods with the prefix "Get"). Now the output is as follows:

    Figure 4: The new output related to the FindMembers() method invocation

    The new output related to the FindMembers() method invocation

    The MemberInfo class has two properties worth noting: one is DeclaringType; the other is ReflectedType, both of which return type Type.

    Note that DeclaringType returns the type that declares the member. Let's recall our previous piece of code:

    It will return all the public members, including the Equals() method inherited from base class. For the Equals() method, its DeclaringType returns the type instance that is equivalent to typeof(Object). This is because it is defined in System.Object while its ReflectedType returns the type instance that is the equivalent to typeof(DemoClass), because it is obtained through the type instance of DemoClass.

    Field Information and the FieldInfo Type

    As said before, MemberInfo is a base class that contains the public information of various members of a specified type. In fact, for the fields, properties, methods, events, and other types of members, they contain information that is clearly not the same. So, .Net provides a FiledInfo type to encapsulate the fields, which is derived from MemberInfo.

    For example, if we want to get all the fields of some type, we can use the GetFileds() method. To exemplify this, let's create another method named FieldExplore():

    Listing 4: Acquire the field info of specified type

    Then, let's put the above method FieldExplore invocation inside the Main method.

    The output result is shown in Figure 5.

    Figure 5: Dump the field info of the class DemoClass

    Dump the field info of the class DemoClass

    It is worth mentioning that the fi.FieldType property returns a bit tag called FieldAttributes which contains the attribute information of the field. Compared with our previously-defined DemoClass class, we can see for the field title, its attributes are public and InitOnly, while for the const type field text, its attributes are Public, Static, Literal, and HasDefault. From this, it can be deduced that declaring a variable of const type, it is by default of static type. At the same time, because we gave it an initial value, the bit tags also include HasDefault.

    As for the bit flags FieldType, class FiledInfo provides a set of attributes to return the bool type, to illustrate the target field related information, commonly used being IsPublic, IsStatic, IsInitOnly, IsLiteral, IsPrivate, and so on.

    Note if we want to obtain private fields associated information, we can still use the overriden GetFields() method, passing in the BindingFlags parameter, similar to the above. But, we are not going to repeat here.

    Attribute Information and the PropertyInfo Type

    Similar to fields, we can also, through the GetProperty() method, acquire all the property information of the target type.

    To check out the above conclusion, let's construct another example method named PropertyExplore:

    Listing 5: Acquire the property info of specified type

    Now, let's look at the above method PropertyExplore invocation inside the Main method.

    The corresponding running-time snapshot is shown in Figure 6.

    Figure 6: Dump the property info of the class DemoClass

    Dump the property info of the class DemoClass

    As seen from the preceding samples, the Name property, after compilation, will be generated into two methods: Get_Name() and Set_Name(). Thus, we are able to get the two methods using reflection. In detail, we can accomplish this via the two methods - GetGetMethod() and GetSetMethod() of class PropertyInfo, both of which will return a MethodInfo object that encapsulates information about the method, to be covered later.

    Method Information and the MethodInfo Type

    Similar to the previous, we can still write code to view the method information of some type.

    Listing 6: Acquire the method info of specified type

    Similar to the previous, class MethodInfo also has an Attributes property, which returns a MethodAttribute. MethodAttribute owns a set of bit flags, indicating some properties of the method, such as Abstract, Static, Virtual, Public, Private, and so on.

    The difference from the preceding ones lies in that methods can have parameters and returned values. Class MethodInfo provides a GetParameters() method to get an array of parameter objects. The method related parameters are all encapsulated in the ParameterInfo type. The approach to view the ParameterInfo type is similar to the previous ones, not to be described any more here.

    Now, let's look at the running-time snapshot of the above case, as shown in Figure 7 below.

    Figure 7: Dump the method info of the class DemoClass

    Dump the method info of the class DemoClass

    The ConstructorInfo Type and the EventInfo Type

    As seen from the name, these two types encapsulate the constructor and event related information of a specified type. Till this point, I think you readers can surely dig into them, using the ways like above, by yourselves. Thus, we are not going to repeat them, too.

    Summary

    This article still involved the most basic content concerning .NET reflection. As you've seen, we can use the reflection from top to down to view the information of an assembly, module, type, and type members. In fact, there are more powerful and interesting content related to reflection, such as late binding method, dynamically creating a type. All of these will be discussed in the next articles.

    The C# 4.0 Reflection Programming series

  • Part 1 An introduction to Reflection in C#.
  • Part 2 As introduced in the first article, the most typically-used tools associated with .NET reflection are: the Type class and Assembly class related members. In this second article, we are going to pick up the .NET reflection tools to set up more samples to explore the wide and extensive use of reflection.
  • Part 3 In the previous article, we used the reflection to obtain the information of an assembly, module, type, and type members. In this article, we'll turn to discuss another important aspect related to reflection-Attribute programming. We are going to first look at the mostly-used .NET built-in Attributes, and then try to write a custom Attribute. At last, we'll rest upon reflection to acquire the custom attribute info.
  • Part 4 In this last article of this series, we will learn what to do with reflection. But before making the topic more interesting, we'll first look at how to dynamically create an object.
  • <<  Previous Article Continue reading and see our next or previous articles Next Article >>

    About Xianzhong Zhu

    I'm a college teacher and also a freelance developer and writer from WeiFang China, with more than fourteen years of experience in design, and development of various kinds of products and applications on Windows platform. My expertise is in Visual C++/Basic/C#, SQL Server 2000/2005/2008, PHP+MyS...

    This author has published 81 articles on DotNetSlackers. View other articles or the complete profile here.

    Other articles in this category


    C# 4.0 Reflection Programming - Part 1
    An introduction to Reflection in C#.
    C# 4.0 Reflection Programming - Part 3
    In the previous article, we used the reflection to obtain the information of an assembly, module, ty...
    C# 4.0 Reflection Programming - Part 4
    In this last article of this series, we will learn what to do with reflection. But before making the...
    Understanding and Using Extension Methods
    Extension methods were new to C# 3.0. They allow you to add a method to an existing type without hav...
    Introduction to C# 3.0 features
    C# 3.0 introduced some of very useful features built on top of 2.0. This article explains the usage,...

    You might also be interested in the following related blog posts


    Introducing SharePoint 2010 Training at U2U read more
    The Underground at PDC read more
    Building A Product For Real read more
    My History of Visual Studio (Part 6) read more
    F# in VS2010 read more
    My History of Visual Studio (Part 5) read more
    BeginDialOut with Office Communicator Clients read more
    DotNetNuke Fusion Results for Q3 read more
    GiveCamps Get a new Sponsor read more
    Announcing the WebsiteSpark Program read more
    Top
     
     
     

    Please login to rate or to leave a comment.