Filtering Output When Obtaining Members






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 obtain only the static constructor of a type, or you need 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 code shown here in Figure.

Filtering members

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);
    }
}

This example examines 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 is passed to the Type.GetFields method, only public fields are returned. If both the BindingFlags. Public and BindingFlags.NonPublic flags are passed to the Type.GetFields method, the list of fields is expanded to include the protected, internal, protected internal, and private fields of a type. Figure lists and describes each flag in the BindingFlags enumeration.

Relevant binding flag definitions

Flag name

Definition

IgnoreCase

Case sensitivity is turned off.

Instance

Include all instance members when obtaining members of a type.

NonPublic

Include all nonpublic members when obtaining members of a type.

Public

Include all public members when obtaining members of a type.

Static

Include all static members when obtaining members of a type.


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 Figure.

Reflection permission flags

Permission flag

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 is 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 pass just 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.



 Python   SQL   Java   php   Perl 
 game development   web development   internet   *nix   graphics   hardware 
 telecommunications   C++ 
 Flash   Active Directory   Windows