-
-
Notifications
You must be signed in to change notification settings - Fork 57
Using Delegates
These are the topics you'll find covered on this page:
- Introduction
- Delegates
- Creating instances
- Accessing fields
- Accessing properties
- Accessing indexers
- Accessing arrays
- Accessing methods
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 Accessing with Fasterflect.
As mentioned this section about caching, you can significantly speed up the construction invocation and member access performance in Fasterflect by directly using the delegates dynamically constructed by Fasterflect. (See the Benchmarks to know how many times faster the direct use of delegates can result in. Fasterflect exposes extension methods for System.Type and metadata (such as FieldInfo and MethodInfo) to allow you retrieve such delegates.
All delegate types declared by Fasterflect and available for direct use are declared in Common/Delegates.cs file.
namespace Fasterflect
{
/// <summary>
/// A delegate to retrieve the value of a static field or property of a type.
/// </summary>
public delegate object StaticMemberGetter();
/// <summary>
/// A delegate to retrieve the value of an instance field or property of an object.
/// </summary>
/// <param name="target">The object whose field's or property's value is to be retrieved.</param>
/// <returns>The value of the instance field or property.</returns>
public delegate object MemberGetter( object target );
/// <summary>
/// A delegate to set the value of a static field or property of a type.
/// </summary>
/// <param name="value">The value to be set to the field or property.</param>
public delegate void StaticMemberSetter( object value );
/// <summary>
/// A delegate to set the value of an instance field or property of an object.
/// </summary>
/// <param name="target">The object whose field's or property's value is to be set.</param>
/// <param name="value">The value to be set to the field or property.</param>
public delegate void MemberSetter( object target, object value );
/// <summary>
/// A delegate to set an element of an array.
/// </summary>
/// <param name="array">The array whose element is to be set.</param>
/// <param name="index">The index of the element to be set.</param>
/// <param name="value">The value to set to the element.</param>
public delegate void ArrayElementSetter( object array, int index, object value );
/// <summary>
/// A delegate to retrieve an element of an array.
/// </summary>
/// <param name="array">The array whose element is to be retrieved</param>
/// <param name="index">The index of the element to be retrieved</param>
/// <returns>The element at <paramref name="index"/></returns>
public delegate object ArrayElementGetter( object array, int index );
/// <summary>
/// A delegate to invoke a static method of a type.
/// </summary>
/// <param name="parameters">The properly-ordered parameter list of the method.</param>
/// <returns>The return value of the method. Null is returned if the method has no
/// return type.</returns>
public delegate object StaticMethodInvoker( params object[] parameters );
/// <summary>
/// A delegate to invoke an instance method or indexer of an object.
/// </summary>
/// <param name="target">The object whose method or indexer is to be invoked on.</param>
/// <param name="parameters">The properly-ordered parameter list of the method/indexer.
/// For indexer-set operation, the parameter array include parameters for the indexer plus
/// the value to be set to the indexer.</param>
/// <returns>The return value of the method or indexer. Null is returned if the method has no
/// return type or if it's a indexer-set operation.</returns>
public delegate object MethodInvoker( object target, params object[] parameters );
/// <summary>
/// A delegate to invoke the constructor of a type.
/// </summary>
/// <param name="parameters">The properly-ordered parameter list of the constructor.</param>
/// <returns>An instance of type whose constructor is invoked.</returns>
public delegate object ConstructorInvoker( params object[] parameters );
/// <summary>
/// A delegate to copy values of instance members (fields, properties, or both) from one object to another.
/// </summary>
/// <param name="source">The object whose instance members' values will be read.</param>
/// <param name="target">The object whose instance members' values will be written.</param>
public delegate void ObjectMapper( object source, object target );
}
The extension methods allowing you to retrieve the constructed delegates to create object instances are:
ConstructorInvoker DelegateForCreateInstance( this Type type, params Type[] parameterTypes );
ConstructorInvoker DelegateForCreateInstance( this Type type, Flags bindingFlags, params Type[] parameterTypes );
ConstructorInvoker DelegateForCreateInstance( this ConstructorInfo ctorInfo );
Sample usage:
// Create the delegate to the 1-string-argument constructor of class Person
// CIL for the delegate is generated now, if not already generated
var ctor = typeof(Person).DelegateForCreateInstance(typeof(string));
while (longLoop) {
object person = ctor(name); // almost as fast as native constructor invocation
}
The extension methods allowing you to retrieve the constructed delegates to get/set fields are:
MemberGetter DelegateForGetFieldValue( this Type type, string name );
MemberGetter DelegateForGetFieldValue( this Type type, string name, Flags bindingFlags );
MemberSetter DelegateForSetFieldValue( this Type type, string name );
MemberSetter DelegateForSetFieldValue( this Type type, string name, Flags bindingFlags );
StaticMemberGetter DelegateForGetStaticFieldValue( this Type type, string name );
StaticMemberGetter DelegateForGetStaticFieldValue( this Type type, string name, Flags bindingFlags );
StaticMemberSetter DelegateForSetStaticFieldValue( this Type type, string name );
StaticMemberSetter DelegateForSetStaticFieldValue( this Type type, string name, Flags bindingFlags );
MemberGetter DelegateForGetFieldValue( this FieldInfo fieldInfo );
MemberSetter DelegateForSetFieldValue( this FieldInfo fieldInfo );
StaticMemberGetter DelegateForGetStaticFieldValue( this FieldInfo fieldInfo );
StaticMemberSetter DelegateForSetStaticFieldValue( this FieldInfo fieldInfo );
Sample usage:
var type = typeof(Person);
MemberSetter setter = type.DelegateForSetFieldValue("name");
MemberGetter getter = type.DelegateForGetFieldValue("name");
var person = type.CreateInstance();
// the delegates are reused through all iterations
while (longLoop) {
setter(person, name);
name = getter(person);
}
The rest of this page shows all other extension methods to create delegates in Fasterflect. Their usages can easily be inferred from the above examples as well as the detailed documentation available in Standard Access.
MemberGetter DelegateForGetPropertyValue( this Type type, string name );
MemberGetter DelegateForGetPropertyValue( this Type type, string name, Flags bindingFlags );
StaticMemberGetter DelegateForGetStaticPropertyValue( this Type type, string name );
StaticMemberGetter DelegateForGetStaticPropertyValue( this Type type, string name, Flags bindingFlags );
MemberSetter DelegateForSetPropertyValue( this Type type, string name );
MemberSetter DelegateForSetPropertyValue( this Type type, string name, Flags bindingFlags );
StaticMemberSetter DelegateForSetStaticPropertyValue( this Type type, string name );
StaticMemberSetter DelegateForSetStaticPropertyValue( this Type type, string name, Flags bindingFlags );
MemberGetter DelegateForGetPropertyValue( this PropertyInfo propInfo );
MemberSetter DelegateForSetPropertyValue( this PropertyInfo propInfo );
StaticMemberGetter DelegateForGetStaticPropertyValue( this PropertyInfo propInfo );
StaticMemberSetter DelegateForSetStaticPropertyValue( this PropertyInfo propInfo );
MethodInvoker DelegateForGetIndexer( this Type type, params Type[] parameterTypes );
MethodInvoker DelegateForGetIndexer( this Type type, Flags bindingFlags, params Type[] parameterTypes );
MethodInvoker DelegateForSetIndexer( this Type type, params Type[] parameterTypes );
MethodInvoker DelegateForSetIndexer( this Type type, Flags bindingFlags, params Type[] parameterTypes );
ArrayElementGetter DelegateForGetElement( this Type arrayType );
ArrayElementSetter DelegateForSetElement( this Type arrayType );
MethodInvoker DelegateForCallMethod( this Type type, string name, params Type[] parameterTypes );
MethodInvoker DelegateForCallMethod( this Type type, string name, Flags bindingFlags, params Type[] parameterTypes );
StaticMethodInvoker DelegateForCallStaticMethod( this Type type, string name, params Type[] parameterTypes );
StaticMethodInvoker DelegateForCallStaticMethod( this Type type, string name, Flags bindingFlags, params Type[] parameterTypes );
MethodInvoker DelegateForCallMethod( this MethodInfo methodInfo );
StaticMethodInvoker DelegateForCallStaticMethod( this MethodInfo methodInfo );