Recipe13.10.Filtering Output When Obtaining Members


Recipe 13.10. 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 Example 13-3.

Example 13-3. 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. Table 13-2 lists and describes each flag in the BindingFlags enumeration.

Table 13-2. 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 Table 13-3.

Table 13-3. 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.



C# Cookbook
Secure Programming Cookbook for C and C++: Recipes for Cryptography, Authentication, Input Validation & More
ISBN: 0596003943
EAN: 2147483647
Year: 2004
Pages: 424

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net