DekGenius.com
[ Team LiB ] Previous Section Next Section

Recipe 12.11 Filtering Output when Obtaining Members

Problem

You want to get information about one or more members, but you want to retrieve only a subset of members. For example, you need to use Type.GetConstructor to obtain only the static constructor of a type, or you need to use Type.GetField to obtain only the noninherited nonpublic fields of a type.

Solution

Use the BindingFlags enumeration together with the appropriate Type.Getxxx methods to find out about the type, as in the following example:

public static void FilteringOutputObtainingMembers( )
{
    Type reflection = typeof(Reflection);
    ConstructorInfo[] constructors = 
        reflection.GetConstructors(BindingFlags.Public |
                                    BindingFlags.NonPublic |
                                    BindingFlags.Instance | 
                                    BindingFlags.Static);

    Console.WriteLine("Looking for All Constructors");
    foreach(ConstructorInfo c in constructors)
    {
        Console.WriteLine("\tFound Constructor {0}",c.Name);
    }

    constructors = 
        reflection.GetConstructors(BindingFlags.Public | 
                                    BindingFlags.Instance);
    Console.WriteLine("Looking for Public Instance Constructors");
    foreach(ConstructorInfo c in constructors)
    {
        Console.WriteLine("\tFound Constructor {0}",c.Name);
    }

    constructors = 
        reflection.GetConstructors(BindingFlags.NonPublic |
                                    BindingFlags.Instance | 
                                    BindingFlags.Static);
    Console.WriteLine("Looking for NonPublic Constructors");
    foreach(ConstructorInfo c in constructors)
    {
        Console.WriteLine("\tFound Constructor {0}",c.Name);
    }

    FieldInfo[] fields = 
        reflection.GetFields(BindingFlags.Static | 
                                BindingFlags.Public);
    Console.WriteLine("Looking for Public, Static Fields");
    foreach(FieldInfo f in fields)
    {
        Console.WriteLine("\tFound Field {0}",f.Name);
    }

    fields = 
        reflection.GetFields(BindingFlags.Public |
                                BindingFlags.Static |
                                BindingFlags.Instance);
    Console.WriteLine("Looking for Public Fields");
    foreach(FieldInfo f in fields)
    {
        Console.WriteLine("\tFound Field {0}",f.Name);
    }

    fields = 
        reflection.GetFields(BindingFlags.NonPublic |
                                BindingFlags.Static );
    Console.WriteLine("Looking for NonPublic, Static Fields");
    foreach(FieldInfo f in fields)
    {
        Console.WriteLine("\tFound Field {0}",f.Name);
    }

}

In this example, we examine the CSharpRecipes.Reflection type for constructors and fields. The constructors and fields are listed here:

#region Fields
     int i = 0;
     public int pi = 0;
     static int si = 0;
     public static int psi = 0;
     object o = null;
     public object po = null;
     static object so = null;
     public static object pso = null;
#endregion

#region Constructors
     static Reflection( )
     {
        si++;
        psi = 0;
        so = new Object( );
        pso = new Object( );
     }

     Reflection( )
     {
        i = 0;
        pi = 0;
        o = new Object( );
        po = new Object( );
     }

     public Reflection(int index)
     {
        i = index;
        pi = index;
        o = new Object( );
        po = new Object( );
     }
#endregion

The output this generates is listed here:

Looking for All Constructors
        Found Constructor .cctor
        Found Constructor .ctor
        Found Constructor .ctor
Looking for Public Instance Constructors
        Found Constructor .ctor
Looking for NonPublic Constructors
        Found Constructor .cctor
        Found Constructor .ctor
Looking for Public, Static Fields
        Found Field psi
        Found Field pso
Looking for Public Fields
        Found Field pi
        Found Field po
        Found Field psi
        Found Field pso
Looking for NonPublic, Static Fields
        Found Field si
        Found Field so

Discussion

The following methods of the Type object accept a BindingFlags enumerator to filter output:

Type.GetConstructor
Type.GetConstructors
Type.GetMethod
Type.GetMethods
Type.GetField
Type.GetFields
Type.GetProperty
Type.GetProperties
Type.Event
Type.Events
Type.GetMember
Type.GetMembers
Type.FindMembers

The following are also methods that accept a BindingFlags enumerator to filter members and types to invoke or instantiate:

Type.InvokeMember
Type.CreateInstance

BindingFlags allows the list of members on which these methods operate to be expanded or limited. For example, if the BindingFlags.Public flag were passed to the Type.GetFields method, only public fields would be returned. If both the BindingFlags.Public and BindingFlags.NonPublic flags were passed to the Type.GetFields method, the list of fields would be expanded to include the protected, internal, protected internal, and private fields of a type. Table 12-2 lists and describes each flag in the BindingFlags enumeration.

Table 12-2. Binding flag definitions

Flag name

Definition

CreateInstance

An instance of a specified type is created while passing in the given arguments to its constructor.

DeclaredOnly

Inherited members are not included when obtaining members of a type.

Default

No binding flags are used.

ExactBinding

The specified parameters must exactly match the parameters on the invoked member.

FlattenHierarchy

Static members up the inheritance hierarchy are returned; nested types won't be returned.

GetField

The specified field's value is to be returned.

GetProperty

The specified property's value is to be returned.

IgnoreCase

Case-sensitivity is turned off.

IgnoreReturn

Ignore the returned value when invoking methods on COM objects.

Instance

Include all instance members when obtaining members of a type.

InvokeMethod

The specified method is to be invoked.

NonPublic

Include all nonpublic members when obtaining members of a type.

OptionalParamBinding

Used with the Type.InvokeMember method to invoke methods that contain parameters with default values and methods with variable numbers of parameters (params).

Public

Include all public members when obtaining members of a type.

PutDispProperty

Invoke the PROPPUT member of a COM object.

PutRefDispProperty

Invoke the PROPPUTREF member of a COM object.

SetField

The specified field's value is to be set.

SetProperty

The specified property's value is to be set.

Static

Include all static members when obtaining members of a type.

SuppressChangeType

Not implemented.

Be aware that to examine or invoke nonpublic members, your assembly must have the correct reflection permissions . The reflection permission flags, and what PermissionSets they are included in by default, are listed in Table 12-3.

Table 12-3. ReflectionPermissionFlags

PermissionFlag

Description

Permission sets including these rights

AllFlags

TypeInformation, MemberAccess, and ReflectionEmit are set.

FullTrust , Everything

MemberAccess

Invocation of operations on all type members is allowed. If this flag is not set, only invocation of operations on visible type members is allowed.

FullTrust, Everything

NoFlags

No reflection is allowed on types that are not visible.

All permission sets

ReflectionEmit

Use of System.Reflection.Emit is allowed.

FullTrust, Everything, LocalIntranet

TypeInformation

Reflection is allowed on members of a type that are not visible.

FullTrust, Everything

One other item to note is that when supplying a BindingFlags set of flags for one of the Get* methods, you must always pass either BindingFlags.Instance or BindingFlags.Static in order to get any results back. If you just pass BindingFlags.Public, for example, you will not find any results. You need to pass BindingFlags.Public | BindingFlags.Instance to get public instance results.

See Also

See the "BindingFlags Enumeration," "Type Class," "ConstructorInfo Class," and "FieldInfo Class" topics in the MSDN documentation.

    [ Team LiB ] Previous Section Next Section