This project has moved. For the latest updates, please go here.

Standard Queries

These are the topics you'll find covered on this page:

Introduction

Before continuing it is important that you have read the Getting Started page, in particular the section on how to customize the behavior of Fasterflect using Flags, as well as the general introduction to Querying with Fasterflect.

Querying assemblies

The section explains how to query an assembly for types defined within it. Fasterflect provides only two methods for accomplishing this:

IList<Type> Types( this Assembly assembly, params string[] names );
IList<Type> Types( this Assembly assembly, Flags bindingFlags, params string[] names );
As you can tell, both methods allow you pass in an array of names, which can be used to filter the list of types returned if you know the names of the types you're looking for. If you omit the names parameter all types will be returned. The Flags parameter allows you to customize the search, but the underlying Assembly.GetTypes method has no overload that allows you to specify any BindingFlags. This overload is therefore only useful when doing Advanced Queries, such as searching for types by partial name.

// example: find a specific type by name:
Assembly assembly = Assembly.GetAssembly( typeof(int) );
IList<Type> types = assembly.Types( "Int32" );
Assert.AreEqual( typeof(int), types.First() );

Querying types

The section explains how to query types for information. As the options for inspecting types are somewhat more extensive than for assemblies, this section is divided into sub-topics for each of the supported member types you can query for.

Querying for fields

Fasterflect provides the following methods for locating fields on a type:

FieldInfo Field( this Type type, string name );
FieldInfo Field( this Type type, string name, Flags bindingFlags );
IList<FieldInfo> Fields( this Type type, params string[] names );
IList<FieldInfo> Fields( this Type type, Flags bindingFlags, params string[] names );

As explained on the Querying page, methods in singular form return a single field, whereas methods in plural form return a list of fields. When querying for a single field you must supply a name, but when querying for multiple fields you have the option of passing in a list of names against which to filter the result. Note that passing an empty list of names will return the unfiltered results rather than an empty list.

// all query methods work on the type so lets put that in a variable
Type type = obj.GetType(); 

// examples of querying for a single field
// find the public or non-public instance field named exactly "data"
FieldInfo field = type.Field( "data" ); 

// same as above but match the name case-insensitively
field = type.Field( "data", Flags.InstanceAnyVisibility | Flags.IgnoreCase ); 

// find the public or non-public static field named exactly "data"
field = type.Field( "data", Flags.StaticAnyVisibility ); 

// examples of querying for multiple fields
// find all instance fields
IList<FieldInfo> fields = type.Fields();

// find static fields declared on type that match "foo" or "bar" case-insensitively
fields = type.Fields( Flags.StaticAnyDeclaredOnly | Flags.IgnoreCase, "foo", "bar" );

Querying for properties

Fasterflect provides the following methods for locating properties on a type:

PropertyInfo Property( this Type type, string name );
PropertyInfo Property( this Type type, string name, Flags bindingFlags );
IList<PropertyInfo> Properties( this Type type, params string[] names );
IList<PropertyInfo> Properties( this Type type, Flags bindingFlags, params string[] names );

It should be very obvious that these correspond exactly to the overloads available for locating fields. As such, if you substitute Field for Property and Fields for Properties in the previous section then the exact same applies when querying for properties.

Querying for fields and properties

Fasterflect provides the following methods for locating both fields and properties on a type:

IList<MemberInfo> FieldsAndProperties( this Type type );
IList<MemberInfo> FieldsAndProperties( this Type type, Flags bindingFlags );

Once again this works exactly like above, although as you can tell there are no singular overloads for selecting only a single field or property, nor are there overloads that allow you to filter the result by a list of names. If you think these would be useful, please voice your request on this issue in the tracker.

One thing to note is that when using one of these methods your result will be a list of MemberInfo instances, each of which will be either a FieldInfo or PropertyInfo. To make it somewhat more convenient to work with these the following MemberInfo extensions have been added:

bool HasName( this MemberInfo member, string name ); // true if MemberInfo.Name equals the given name (single leading underscores are ignored)
bool IsReadable( this MemberInfo member ); // true for fields and properties that have a getter
bool IsWritable( this MemberInfo member ); // true for fields that are not readonly or const and properties that have a setter
Type Type( this MemberInfo member ); // returns either FieldInfo.FieldType or PropertyInfo.PropertyType; throws if not one of these two

Type type = obj.GetType(); 
// example showing how to find all readable instance fields and properties of type string
IList<MemberInfo> fieldsAndProperties = type.FieldsAndProperties().Where( m => m.IsReadable() && m.Type() == typeof(string) ).ToList();

Querying for methods

Fasterflect provides the following methods for locating methods on a type. It should be noted that constructors are not considered methods.

MethodInfo Method( this Type type, string name );
MethodInfo Method( this Type type, string name, Flags bindingFlags );
MethodInfo Method( this Type type, string name, Flags bindingFlags, Type[] parameterTypes );
IList<MethodInfo> Methods( this Type type, params string[] names );
IList<MethodInfo> Methods( this Type type, Flags bindingFlags, params string[] names );
IList<MethodInfo> Methods( this Type type, Type[] parameterTypes, Flags bindingFlags, params string[] names );

Once again our set of overloads are very similar to the options offered for searching for fields and properties, and the same semantics and defaults apply to these query methods. Here we have an additional two overloads allowing you to filter the result by requiring found methods to define parameters that match the specified array of parameter types. Note that the parameterTypes parameter is not an optional argument and that passing an empty list will restrict the result set to methods that have no parameters. This is unlike the names parameter, which restricts the result set to methods with one of the specified names. If this parameter is null or does not contain at least one name then no name filtering will be applied.

When working with methods or constructors, sometimes you also want to inspect their parameters. The following method allows you to retrieve the parameter list for a method or constructor:

IList<ParameterInfo> Parameters( this MethodBase method );

Querying for constructors

Fasterflect provides the following methods for locating constructors on a type:

ConstructorInfo Constructor( this Type type, params Type[] parameterTypes );
ConstructorInfo Constructor( this Type type, Flags bindingFlags, params Type[] parameterTypes );
IList<ConstructorInfo> Constructors( this Type type );
IList<ConstructorInfo> Constructors( this Type type, Flags bindingFlags );

Unlike the member types covered previously, constructors all have the same name (".ctor" for instance constructors and ".cctor" for static constructors), so there are no overloads for locating constructors by name. Another notable difference to the extensions for locating methods is that the parameterTypes parameter is now an optional list of parameters. As explained on the Querying page this implies that passing null and an empty list will be treated identically (both as if an empty list was passed).

Type type = obj.GetType();
// example showing how to locate the default constructor for a type
ConstructorInfo constructor = type.Constructor();
// example showing how to locate a constructor expecting a specific parameter list
constructor = type.Constructor( typeof(int), typeof(string) );

Querying for members of any type

Fasterflect provides the following methods for locating members of any kind on a type.

MemberInfo Member( this Type type, string name );
MemberInfo Member( this Type type, string name, Flags bindingFlags );
IList<MemberInfo> Members( this Type type, MemberTypes memberTypes );
IList<MemberInfo> Members( this Type type, Flags bindingFlags );
IList<MemberInfo> Members( this Type type, MemberTypes memberTypes, Flags bindingFlags, params string[] names );

Once again there are many similarities with the previously covered extensions. The only difference is that we have overloads allowing us to specify a combination of MemberTypes that we wish to include. Overloads that do not have this parameter will use MemberTypes.All as the default value.

Note that searching for multiple member types will cause a reflection lookup for every specified type, even when all MemberTypes are to be returned. This is an internal reflection limitation and not a side-effect introduced by Fasterflect. The net result of this is that searching for members will typically be much slower than searching for a specific type. You should therefore strongly consider using the specific lookup methods or passing a MemberTypes combination with only the desired types of members, rather than relying on the default value for this parameter.

Querying for attributes

This section has not yet been completed. Stay tuned!

Attribute Attribute( this ICustomAttributeProvider source );
Attribute Attribute( this ICustomAttributeProvider source, Type attributeType );
T Attribute<T>( this ICustomAttributeProvider source ) where T : Attribute;
IList<Attribute> Attributes( this ICustomAttributeProvider source, params Type[] attributeTypes );
IList<T> Attributes<T>( this ICustomAttributeProvider source ) where T : Attribute;

Attribute Attribute( this Enum source, Type attributeType );
T Attribute<T>( this Enum source ) where T : Attribute;
IList<Attribute> Attributes( this Enum source, params Type[] attributeTypes );
IList<T> Attributes<T>( this Enum source ) where T : Attribute;

// find types with attributes
IList<Type> TypesWith( this Assembly assembly, Type attributeType );
IList<Type> TypesWith( this Assembly assembly );
// find members with attributes
IList<MemberInfo> MembersWith( this Type type, MemberTypes memberTypes, params Type[] attributeTypes );
IList<MemberInfo> MembersWith( this Type type, MemberTypes memberTypes, Flags bindingFlags );
IList<MemberInfo> MembersWith( this Type type, MemberTypes memberTypes, Flags bindingFlags, params Type[] attributeTypes );
// convenience methods that call MembersWith internally
IList<MemberInfo> FieldsAndPropertiesWith( this Type type, params Type[] attributeTypes );
IList<MemberInfo> FieldsAndPropertiesWith( this Type type, Flags bindingFlags, params Type[] attributeTypes );
IList<FieldInfo> FieldsWith( this Type type, Flags bindingFlags, params Type[] attributeTypes );
IList<PropertyInfo> PropertiesWith( this Type type, Flags bindingFlags, params Type[] attributeTypes );
IList<MethodInfo> MethodsWith( this Type type, Flags bindingFlags, params Type[] attributeTypes );
IList<ConstructorInfo> ConstructorsWith( this Type type, Flags bindingFlags, params Type[] attributeTypes );
// method that returns both members and their attributes
IDictionary<MemberInfo,List<Attribute>> MembersAndAttributes( this Type type, MemberTypes memberTypes, Flags bindingFlags, params Type[] attributeTypes );

bool HasAllAttributes( this ICustomAttributeProvider source, params Type[] attributeTypes );
bool HasAnyAttribute( this ICustomAttributeProvider source, params Type[] attributeTypes );
bool HasAttribute( this ICustomAttributeProvider source, Type attributeType );
bool HasAttribute<T>( this ICustomAttributeProvider source );

Additional querying helpers

Fasterflect contains a few extensions to query types for their origin and inheritance relationships.

Querying for inheritance information

bool Implements<T>( this Type type )
bool Implements( this Type type, Type interfaceType )
bool Inherits<T>( this Type type )
bool Inherits( this Type type, Type baseType )
bool InheritsOrImplements<T>( this Type type )
bool InheritsOrImplements( this Type type, Type baseType )

The Implements extensions allow you to determine if a given type implements a particular interface, whereas Inherits allows you to check for a particular base class. Use InheritsOrImplements if you want to check for either scenario. The non-generic overloads are provided to allow you to pass in open generic types, as illustrates in the following example:

typeof( IList<> ).Implements( typeof(ICollection<>) ); // true
typeof( List<int> ).ImplementsOrInherits( typeof(IEnumerable<>) ) // true

Querying for origin and getting a pretty name for types

bool IsFrameworkType( this Type type )
string Name( this Type type )

The first of these will return true for types defined in an assembly that has been signed by Microsoft's public key (this should cover at least all the BCL libraries).

The second will print out the name of a type in a way that looks similar (if not identical) to how most people would define the same type when writing code. It will recursively traverse any generic type arguments and pretty print those too.

typeof( Int32 ).Name(); // returns "int"
typeof( List<Nullable<int>> ).Name(); // returns "List<int?>"
typeof( IList<DateTime?> ).Name(); // returns "IList<DateTime?>"

Links

  • Advanced Queries Explains the Fasterflect querying capabilities not available with standard Reflection
  • Accessing Introduces the Fasterflect API for constructing instances and accessing members
  • Documentation Returns you to the documentation index page

Last edited Sep 14, 2012 at 4:22 AM by mertner, version 8

Comments

No comments yet.