[ Team LiB ] |
Recipe 7.7 An Advanced Interface Search MechanismProblemYou are searching for an interface using the Type class. However, complex interface searches are not available through the GetInterface and GetInterfaces methods of a Type object. The GetInterface method searches for an interface only by name (using a case-sensitive or -insensitive search), and the GetInterfaces method returns an array of all the interfaces implemented on a particular type. You want a more focused searching mechanism that might involve searching for interfaces that define a method with a specific signature or implemented interfaces that are loaded from the Global Assembly Cache (GAC). You need more flexible and more advanced searching for interfaces that does not involve creating your own interface search engine. SolutionThe FindInterfaces method of a Type object can be used along with a callback to perform complex searches of interfaces on a type. The following method will call a custom interface searching method, SearchInterfacesOfType: using System; using System.Reflection; public class SearchType { public void FindSpecificInterfaces( ) { Type[] names = new Type[3] {Type.GetType("System.ICloneable"), Type.GetType("System.Collections.ICollection"), Type.GetType("System.IAppDomainSetup")}; Type[] interfaces = SearchInterfacesOfType(Type.GetType( "System.Collections.ArrayList"), names); if (interfaces.Length > 0) { Console.WriteLine("Matches found:"); for(int counter =0; counter < interfaces.Length; counter++) { Console.WriteLine("\tIFace Name: " + interfaces[counter].ToString( )); Console.WriteLine("\tIFace Base Type: " + interfaces[counter].BaseType); foreach (object attr in interfaces[counter].GetCustomAttributes(false)) { Console.WriteLine("\t\tIFace attr: " + attr.ToString( )); } } } else { Console.WriteLine("\t\tNo matches found"); } } public Type[] SearchInterfacesOfType(Type searchedType, Type[] ifaceNames) { TypeFilter filter = new TypeFilter(IfaceFilterCallback); Type[] interfaces = searchedType.FindInterfaces(filter, ifaceNames); return (interfaces); } public bool IfaceFilterCallback(Type type, object criteria) { foreach (Type ifaceName in (Type[])criteria) { if(type.FullName == ifaceName.FullName) { return (true); } } return (false); } } The FindSpecificInterfaces method searches for any of the three interface types, contained in the Names array that are implemented by the System.Collections.ArrayList type. The SearchinterfacesOfType method accepts a type (searchedType) on which to search for interfaces and an object (ifaceNames) that contains criteria for the search. For this method, the criterion is a Type array of interfaces. This method then calls the FindInterfaces method on the searchedType parameter and passes in a delegate and the Type array criteria of interfaces. (The delegate will be called back to for each found interface.) This method then returns an array of interface types that match the criterion. The TypeFilter delegate, filter, defines the IfaceFilterCallback method to be called for each interface found on the searchedType object. The real power of this search mechanism lies in the IfaceFilterCallback callback method. This callback searches for each of the interface types in the criteria array that is implemented by the searchedType parameter of the SearchInterfacesOfType method. DiscussionMost complex member searches can be performed only through the use of the FindInterfaces method of a Type object. This method makes use of the TypeFilter delegate, which is passed to the filter parameter. This delegate is supplied by the FCL and allows an extra layer of filtering (of any type that you want) to occur. This delegate returns a Boolean value, where true indicates that the ifaceType object passed to this delegate should be included in the Type array that the FindInterfaces method returns; false indicates that this ifaceType object should not be included.
There are many ways to use this TypeFilter delegate to search for interfaces implemented on a type—here are just a few other searches that can be performed:
See AlsoSee Recipe 7.8; see the "Delegate Class" and "Type.FindInterfaces Method" topics in the MSDN documentation. |
[ Team LiB ] |