Central to reflection is the abstract System.Reflection.MemberInfo class. Concrete classes are derived from MemberInfo to form representations of each member type, including constructors, methods, properties, and fields. For general information about each of the .NET member types, see Chapter 5.
Instances of classes derived from MemberInfo are obtained through the methods of the System.Type class; these methods are grouped by the member type they reflect and follow a clear pattern, each offering three forms, as shown in the following list:
GetXXX(System.Type[])
GetXXXs(System.Reflection.BindingFlags)
GetXXXs()
The XXX indicates a member type—for example, GetConstructor(Type[]), GetConstructors(BindingFlags), and GetConstructors(). The types returned from these methods are derived implementations of MemberInfo named to reflect the member that has been reflected: for example, the GetConstructors method returns instances of ConstructorInfo, and the GetFields method returns instances of FieldInfo.
The first form searches for a member that accepts arguments that match the types specified in the argument array. The following example demonstrates obtaining the System.String constructor that accepts a character array:
Type x_string_type = typeof(System.String); ConstructorInfo x_constructor = x_string_type.GetConstructor(new Type[] {typeof(char[])});
The second form accepts a System.Reflection.BindingFlags value, which specifies attributes that the member must possess in order to be included in the search results. The BindingFlags enumeration is annotated with the FlagsAttribute attribute, so the values can be combined using bitwise operations.
The most commonly used values from the BindingFlags enumeration are
Public
NonPublic
Instance
Static
The following example demonstrates how to combine BindingFlags values to obtain a list of the public instance constructors for a type, in this case the System.String class:
Type x_string_type = typeof(System.String); BindingFlags x_flags = BindingFlags.Public | BindingFlags.Instance; ConstructorInfo[] x_constructors = x_string_type.GetConstructors(x_flags);
To obtain information about all of the members of a type, the following combination of BindingFlags values must be used:
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static
The final GetXXX method form takes no arguments and is equivalent to specifying the Public and Instance binding flags, as shown in the preceding example.
Table 12-3 lists the methods of the System.Type class that can be used to obtain instances of MemberInfo or derived classes, contrasted against the comparable Java reflection functionality.
Table 12-3. Comparison Between Java Reflection and .NET System.Type Class Methods
java.lang.Class | System.Type |
---|---|
N/A | GetMember( ) |
GetMembers( ) | |
getConstructor() | GetConstructor( ) |
getConstructors() | GetConstructors( ) |
getDeclaredConstructor() | |
getDeclaredConstructors() | |
getField() | GetField( ) |
getFields() | GetFields( ) |
getDeclaredField() | |
getDeclaredFields() | |
getMethod() | GetMethod( ) |
getMethods() | GetMethods( ) |
getDeclaredMethod() | |
getDeclaredMethods() | |
N/A | GetEvent( ) |
GetEvents( ) | |
N/A | GetProperty() |
GetProperties( ) |
Once a MemberInfo class has been obtained, several methods, detailed in Table 12-4, are available to obtain type information.
Table 12-4. Methods Available from the MemberInfo Class
Member | Description |
---|---|
DeclaringType | Returns the type that contains the member. |
MemberType | Returns a value from the System.Reflection.MemberTypes enumeration indicating the type of member represented (constructor, method, field, and so on). |
Name | Returns the name of the member. |
ReflectedType | Returns the instance of System.Type that was used to obtain the MemberInfo instance. |
GetCustomAttributes() | See the Inspecting Attributes section later in this chapter for more information. |
IsDefined() | See the Inspecting Attributes section for more information. |
The System.Reflection.MethodBase class is an abstract derivation of MemberInfo that contains additional functionality to reflect on methods. Two concrete subclasses of MethodBase exist: ConstructorInfo and MethodInfo. The following example demonstrates how to obtain the public instance method and constructor information for the System.String class:
Type x_string_type = typeof(System.String); ConstructorInfo[] x_constructors = x_string_type.GetConstructors(); foreach (ConstructorInfo x_into in x_constructors) { Console.WriteLine("Constructor: " + x_into); } Console.WriteLine(); MethodInfo[] x_methods = x_string_type.GetMethods(); foreach (MethodInfo x_info in x_methods) { Console.WriteLine("Method: " + x_info); }
The first few lines of the output are listed next; the String class contains too many members to list completely:
Constructor: Void .ctor(Char*) Constructor: Void .ctor(Char*, Int32, Int32) Constructor: Void .ctor(SByte*) Constructor: Void .ctor(SByte*, Int32, Int32) Constructor: Void .ctor(SByte*, Int32, Int32, System.Text.Encoding) Constructor: Void .ctor(Char[], Int32, Int32) Constructor: Void .ctor(Char[]) Constructor: Void .ctor(Char, Int32) Method: System.String ToString(System.IFormatProvider) Method: System.TypeCode GetTypeCode() Method: System.Object Clone() Method: Int32 CompareTo(System.Object) Method: Int32 GetHashCode() Method: Boolean Equals(System.Object) Method: System.String ToString()
The .NET ConstructorInfo class is equivalent to the Java java.lang.reflect.Constructor class. Table 12-5 compares these two classes.
Table 12-5. Comparison Between the Java Constructor Class and the .NET ConstructorInfo Class
Java Constructor Class | .NET ConstructorInfo Class | Comments |
---|---|---|
getDeclaringClass() | DeclaringType | |
getExceptionTypes() | N/A | |
getModifiers() | Attributes | The Attributes property returns a value from the MethodAttributes enumeration. |
getName() | Name | In .NET applications, normal constructors are denoted by .ctor, while static constructors are denoted by .cctor. |
getParameterTypes() | GetParameters() | See the Inspecting Parameters section later in this chapter for more information. |
newInstance() | Invoke() | See the Late Binding section later in this chapter for more information. |
The .NET MethodInfo class is equivalent to the java.lang.reflect.Method class. These two classes are compared in Table 12-6.
Table 12-6. Comparison Between the Java Method Class and the .NET MethodInfo Class
Java Method Class | .NET MethodInfo Class | Comments |
---|---|---|
getDeclaringClass() | DeclaringType | |
getExceptionTypes() | N/A | |
getModifiers() | Attributes | The Attributes property returns a value from the MethodAttributes enumeration. |
getName() | Name | |
getParameterTypes() | GetParameters() | See the Inspecting Parameters section for more information. |
getReturnType() | ReturnType | |
invoke() | Invoke() | See the Late Binding section for more information. |
The MethodBase class defines convenience members implemented by ConstructorInfo and MethodInfo that provide more details about method-type members. These details can also be derived from inspecting the contents of the Attributes property of ConstructorInfo and MethodInfo. These methods are summarized in Table 12-7.
Table 12-7. The MethodBase Convenience Members
MethodBase Member | Description |
---|---|
IsAbstract | Returns true if the method is abstract. |
IsAssembly | Returns true if the method can be called by other types in the same assembly. |
IsConstructor | Returns true if the method is a constructor. |
IsPrivate | Returns true if the method is private. |
IsPublic | Returns true if the method is public. |
IsStatic | Returns true if the method is static. |
IsVirtual | Returns true if the method is virtual. |
Properties are represented by the System.Reflection.PropertyInfo class; the members of this class are listed in Table 12-8.
Table 12-8. The PropertyInfo Members
PropertyInfo Member | Description |
---|---|
CanRead | Returns true if the property has a get accessor. |
CanWrite | Returns true if the property has a set accessor. |
PropertyType | Returns a System.Type instance representing the type handled by the property. |
GetAccessors() | Returns a MethodInfo array representing the get and set accessors for the property. |
GetGetMethod() | Returns a MethodInfo representing the property get accessor. |
GetSetMethod() | Returns a MethodInfo representing the property set accessor. |
GetIndexParameters() | Returns a ParameterInfo array representing the arguments to the property. See the Inspecting Parameters section for more information about the ParameterInfo class. |
Gets the value of the property for a given instance of the declaring type. See the Late Binding section for more information. | |
SetValue() | Sets the value of the property for a given instance of the declaring type. See the Late Binding section for more information. |
Events are represented by the EventInfo class; Table 12-9 details the members of this class.
Table 12-9. The EventInfo Members
EventInfo Member | Description |
---|---|
EventHandlerType | Returns a System.Type representing the underlying delegate |
IsMulticast | Returns true if the underlying delegate is a multicast delegate |
AddEventHandler() | Adds an event handler to a specified instance of the event type |
GetAddMethod() | Returns a MethodInfo representing the add method of the event |
GetRaiseMethod() | Returns a MethodInfo representing the raise method of the event |
GetRemoveMethod() | Returns a MethodInfo representing the remove method of the event |
RemoveEventHandler() | Removes an event handler from a specified instance of the type |
The ParameterInfo class is used to represent the definition of parameters that are passed into member functions. Table 12-10 details the methods used to obtain parameter information.
Table 12-10. Methods Used to Obtain Parameter Information
Member Type | Method |
---|---|
Constructor | ConstructorInfo.GetParameters() |
Method | MethodInfo.GetParameters() |
Property | PropertyInfo.GetIndexParameters() |
The ParameterInfo class is required to represent the modifiers that can be applied to parameters, such as out and ref. Java does not support parameter modifiers and thus has no equivalent class.
For details of parameter modifiers, see Chapter 4.
Table 12-11 lists the members available in the ParameterInfo class.
Fields are represented by the FieldInfo class, the equivalent of the java.lang.reflect.Field class. Table 12-12 contrasts these two classes.
Table 12-12. Comparison Between the Java Field and .NET FieldInfo Classes
Field | FieldInfo | Comments |
---|---|---|
get() | GetValue() | Gets the value of a field from a specific instance of the declaring type. |
getBoolean() | ||
getByte() | ||
getChar() | ||
getDouble() | ||
getFloat() | ||
getInt() | ||
getLong() | ||
getShort() | ||
getModifiers() | IsAssembly IsInitOnly IsLiteral IsNotSerialized IsPrivate IsPublic IsStatic | Java encapsulates the modifiers for a field in the java.lang.reflect.Modifiers class. The FieldInfo class makes the same information available through a series of properties. |
Name | Returns the name of the field. | |
getType() | FieldType | Returns the type of the field. |
set() | SetValue() | Sets the value of a field for a specific instance of the declaring type. |
setBoolean() | ||
setByte() | ||
setChar() | ||
setDouble() | ||
setFloat() | ||
setInt() | ||
setLong() | ||
setShort() |
Reflection is available only on custom attributes; it isn’t possible to determine whether a type or a member is annotated with one of the system attributes, such as Serializable. The System.Type class includes properties that go some way toward exposing system properties (such as IsSerializable), but the methods that expose attributes via reflection will return custom attributes only.
The MemberInfo class defines the GetCustomAttributes method, which returns an object array; each element in the array can be cast to an instance of an attribute that has been applied to the member. Once an instance of a custom attribute has been obtained, the values that were declared in the attribute annotation are available through direct member calls; it isn’t necessary to use reflection to work with attributes.
The System.Attribute class defines the static IsDefined method, which allows the programmer to determine whether a specific type of custom attribute has been applied to a member.