[ Team LiB ] |
Recipe 12.11 Filtering Output when Obtaining MembersProblemYou 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. SolutionUse 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 DiscussionThe 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.
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.
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 AlsoSee the "BindingFlags Enumeration," "Type Class," "ConstructorInfo Class," and "FieldInfo Class" topics in the MSDN documentation. |
[ Team LiB ] |