[ Team LiB ] |
Recipe 7.8 An Advanced Member Search MechanismProblemYou are searching for a member within a type using the Type class. However, complex member searches are not available through the GetMember and GetMembers methods of a Type object. The GetMember method searches for a member name only within a type limited by the set of BindingFlags used, and the GetMembers method searches for all members limited by the set of BindingFlags used. BindingFlags is an enumeration of various member types that can be searched. The BindingFlags related to this recipe are defined here:
You need to create more flexible and advanced searches for members that do not involve creating your own member search engine. SolutionThe FindMembers method of a Type object can be used, along with a callback, to create your own complex searches. The following method will call our custom member searching method, SearchMembers: using System; using System.Reflection; public class SearchType { public void TestSearchMembers( ) { MemberInfo[] members = SearchMembers(this.GetType( ), Type.GetType("System.Int32")); if (members.Length > 0) { Console.WriteLine("Matches found:"); // Display information for each match for(int counter = 0; counter < members.Length; counter++) { Console.WriteLine("\tMember Name: " + members[counter].ToString( )); Console.WriteLine("\tMember Type: " + members[counter].MemberType); foreach (object attr in members[counter].GetCustomAttributes(false)) { Console.WriteLine("\t\tMember attr: " + attr.ToString( )); } } } else { Console.WriteLine("\t\tNo matches found"); } } public MemberInfo[] SearchMembers(Type searchedType, Type returnType) { // Delegate that compares the member's return type // against the returnType parameter MemberFilter filterCallback = new MemberFilter(ReturnTypeFilter); MemberInfo[] members = searchedType.FindMembers(MemberTypes.All, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static, filterCallback, returnType); return (members); } private bool ReturnTypeFilter(MemberInfo member, object criteria) { // Obtain the return type of either a method or property string returnType = ""; if (member is MethodInfo) { returnType = ((MethodInfo)member).ReturnType.FullName; } else if (member is PropertyInfo) { returnType = ((PropertyInfo)member).PropertyType.FullName; } else { return (false); } // Match return type if (returnType == ((Type)criteria).FullName) { return (true); } else { return (false); } } } This method will search for any member in the current type that has a return value of System.Int32. The SearchMembers method accepts a Type object in which to search and a string representation of the full name of a return type. This method simply calls the FindMembers method of the searchType object passed to it. Notice that the returnType parameter is passed to the FindMembers method as the last parameter. The MemberFilter delegate, filterCallback, defines the ReturnTypeFilter method to be called for each member that meets the specified criteria of the FindMembers method (i.e, MemberTypes.All, BindingFlags.Instance, BindingFlags.Public, BindingFlags.NonPublic, and BindingFlags.Static). The real power of this search mechanism lies in the ReturnTypeFilter callback method. This callback method casts the member parameter to the correct member type (i.e., MethodInfo or PropertyInfo), obtains the return type, and compares that return type to the one passed in to the returnType parameter of the SearchMembers method. A return value of true indicates that the return types matched; a false indicates they did not match. DiscussionMost complex member searches can be performed only through the use of the FindMembers method of a Type object. This method returns an array of MemberInfo objects that contain all members that match the memberType, bindingAttr, and filterCriteria parameters. This method makes use of the MemberFilter delegate, which is passed in to the filter parameter. This delegate is supplied by the FCL and allows an extra layer of member filtering to occur. This filtering can be anything you want. This delegate returns a Boolean value, where true indicates that the member object passed in to this delegate should be included in the MemberInfo array that the FindMembers method returns, and false indicates that this member object should not be included. There are many ways to use this MemberFilter delegate to search for members within a type. Here are just a few other items that can be searched for:
See AlsoSee Recipe 7.7; see the "Delegate Class" and "Type.FindMembers Method" topics in the MSDN documentation. |
[ Team LiB ] |