Skip to content

Standard Access

Ricardo Diaz edited this page Aug 7, 2017 · 1 revision

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 Accessing with Fasterflect. Before working with object construction and indexer/method invocation, you should also read about Accessing Conventions.

Accessing fields

Standard field accessing

This section describes how fields are retrieved and set using Fasterflect. Static field accesses are done through extension methods to System.Type while instance field accesses are done through extension methods to System.Object. The field setters always retrieve the current type or object for chaining purpose. Each method has an overload accepting Flags.

object GetFieldValue( this Type type, string name );
object GetFieldValue( this Type type, string name, Flags bindingFlags );

object GetFieldValue( this object obj, string name );
object GetFieldValue( this object obj, string name, Flags bindingFlags );

Type SetFieldValue( this Type type, string name, object value );
Type SetFieldValue( this Type type, string name, object value, Flags bindingFlags );

object SetFieldValue( this object obj, string name, object value );
object SetFieldValue( this object obj, string name, object value, Flags bindingFlags );

Let's see how easy it is to use these methods. Note that the code below use the CreateInstance extension method of Fasterflect.

Type type = typeof(Person);
type.SetFieldValue("staticIntField", 10).SetFieldValue("staticObjField", anObj);
int i = (int)type.GetFieldValue("staticIntField");

object person = type.CreateInstance();
person.SetFieldValue("name", "tommy").SetFieldValue("age", 15);
string name = (string)person.GetFieldValue("name");
int age = (int)person.GetFieldValue("age");

FieldInfo accessing

Fasterflect also integrates nicely with the .NET Reflection's FieldInfo class via the following extension methods: object Get( this FieldInfo fieldInfo ); object Get( this FieldInfo fieldInfo, object obj ); void Set( this FieldInfo fieldInfo, object value ); void Set( this FieldInfo fieldInfo, object obj, object value );

Sample usage of these methods is shown below. Note that the Field extension method is available by Fasterflect's Querying API.

Type type = typeof(Person);
FieldInfo staticField = type.Field("staticIntField", Flags.StaticAnyVisibility);
staticField.Set(10);
int val = (int)staticField.Get();

FieldInfo field = type.Field("name");
var person = type.CreateInstance();
field.Set(person, "tommy");
string name = (string)field.Get(person);

Try accessing fields

Sometimes you are not sure about the existence of a certain instance field (or its accessibility level) while not wanting to a receive a MissingFieldException when trying to access it. Fasterflect provides convenient helper methods for that. To keep the API simple as well as avoid adding method nobody needs, we don't have overload to work with static fields. If you have this particular need, please submit a feature request in the Issue Tracking tab.

object TryGetFieldValue( this object obj, string name );
object TryGetFieldValue( this object obj, string name, Flags bindingFlags );
bool TrySetFieldValue( this object obj, string name, object value );
bool TrySetFieldValue( this object obj, string name, object value, Flags bindingFlags );

Sample usage is as follow

var person = typeof(Person).CreateInstance();
if (person.TrySetFieldValue("someField", 20)) { // return false if not successful for some reason
    int val = (int) person.TryGetFieldValue("someField"); // return null if not successful for some reason
}

Accessing properties

Property accesses in Fasterflect work the same way with field accesses. As such, if you substitute GetFieldValue for GetPropertyValue and SetFieldValue for SetPropertyValue in the previous section then the exact same applies when accessing properties.

object GetPropertyValue( this Type type, string name );
object GetPropertyValue( this Type type, string name, Flags bindingFlags );

object GetPropertyValue( this object obj, string name );
object GetPropertyValue( this object obj, string name, Flags bindingFlags );

Type SetPropertyValue( this Type type, string name, object value );
Type SetPropertyValue( this Type type, string name, object value, Flags bindingFlags );

object SetPropertyValue( this object obj, string name, object value );
object SetPropertyValue( this object obj, string name, object value, Flags bindingFlags );

object Get( this PropertyInfo propInfo );
object Get( this PropertyInfo propInfo, object obj );

void Set( this PropertyInfo propInfo, object value );
void Set( this PropertyInfo propInfo, object obj, object value );

object TryGetPropertyValue( this object obj, string name );
object TryGetPropertyValue( this object obj, string name, Flags bindingFlags );

bool TrySetPropertyValue( this object obj, string name, object value );
bool TrySetPropertyValue( this object obj, string name, object value, Flags bindingFlags );

Accessing indexers

Fasterflect supports accessing indexers via the methods below. Because there is no concept of static indexer in .NET, the extension methods are defined for System.Object type only. The setter always return the current object for chaining purpose.

object GetIndexer( this object obj, params object[] parameters );
object GetIndexer( this object obj, Type[] parameterTypes, params object[] parameters );
object GetIndexer( this object obj, Flags bindingFlags, params object[] parameters );
object GetIndexer( this object obj, Type[] parameterTypes, Flags bindingFlags, params object[] parameters );

object SetIndexer( this object obj, params object[] parameters );
object SetIndexer( this object obj, Type[] parameterTypes, params object[] parameters );
object SetIndexer( this object obj, Flags bindingFlags, params object[] parameters );
object SetIndexer( this object obj, Type[] parameterTypes, Flags bindingFlags, params object[] parameters );

Assume that the Person class has an indexer defined as follows:

/// <summary>
/// Indexer to a friend object via name.
/// </summary>
public Person this[ string name ]
{
    get { return friends[ name ]; }
    set { friends[ name ] = value; }
}

You can access to that indexer as follows:

// Quick way, when you know that no argument is null
var person = typeof(Person).CreateInstance();
person.SetIndexer("john the buddy", typeof(Person).CreateInstance()); 
var john = person.GetIndexer("john the buddy");

// When one or more arguments to the indexer might be null, you have to specify the parameter type array
person.SetIndexer(new Type[] {typeof(String) /* indexer parameter type */, typeof(Person) /* indexer type */ }, name, anotherPerson); 
var friend = person.GetIndexer(new Type[] {typeof(String)}, name);

Fasterflect allows you to access to indexers with more than one parameters too! The usage is exactly similar to the above (you just need to specify more type parameter and/or argument).

Accessing members

Just as you can get/set fields and properties (and try get/set fields and properties), you can do so without even bothering as to whether a member is field or property with the following extension methods.

object TryGetValue( object obj, string name );
object TryGetValue( object obj, string name, Flags bindingFlags );

bool TrySetValue( object obj, string name, object value );
bool TrySetValue( object obj, string name, object value, Flags bindingFlags );
object Get( MemberInfo memberInfo );
object Get( MemberInfo memberInfo, object obj );

void Set( MemberInfo memberInfo, object value );
void Set( MemberInfo memberInfo, object obj, object value );

Accessing arrays

Working with array is very simple with Fasterflect. The following methods are available to get/set array element.

object GetElement( object array, long index );
object SetElement( object array, long index, object value );

The below code shows you how to create an array dynamically and get/set its elements.

// create an array of 10 elements for the given type
var array = typeof(int[]).CreateInstance(10); 

// set 15 to the array element at index 1th
array.SetElement(1, 15);

// get the value of array element at index 1th
int value = (int) array.GetElement(1); 

Accessing methods

You can invoke both static and instance methods using Fasterflect. Static method invocations are done through extension methods of System.Type while instance method invocations through System.Object. Note the Accessing Conventions when using the overloads not accepting the parameterTypes array.

object CallMethod( this Type type, string name, params object[] parameters );
object CallMethod( this Type type, string name, Type[] parameterTypes, params object[] parameters );
object CallMethod( this Type type, string name, Flags bindingFlags, params object[] parameters );
object CallMethod( this Type type, string name, Type[] parameterTypes, Flags bindingFlags, params object[] parameters );

object CallMethod( this object obj, string name, params object[] parameters );
object CallMethod( this object obj, string name, Type[] parameterTypes, params object[] parameters );
object CallMethod( this object obj, string name, Flags bindingFlags, params object[] parameters );
object CallMethod( this object obj, string name, Type[] parameterTypes, Flags bindingFlags, params object[] parameters );

Sample usage is as follows:

var type = typeof(Employee);
int totalEmployeeInstances = (int) type.CallMethod("GetTotalEmployeeInstances"); // invoke static method

var employee = type.CreateInstance();
double salary = (double) employee.CallMethod("CalculateSalary");

// invoke method with one argument
employee.CallMethod("SetTitle", "Engineer"); 
employee.CallMethod("SetTitle", new Type[] {typeof(string)}, mightBeNullTitleValue);

Fasterflect also integrates with MethodInfo so that you can perform invocation directly on instances of MethodInfo. 
object Call( this MethodInfo methodInfo, params object[] parameters );
object Call( this MethodInfo methodInfo, object obj, params object[] parameters );

Sample usage is as follows:

var methodInfo = typeof(Employee).Method( "Walk", new [] { typeof(int) }, Flags.InstanceAnyVisibility );
var employee = typeof(Employee).CreateInstance();
methodInfo.Call(employee, 10d); // walk 10 meters