BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

Reflection
.NET 1.1+

Accessing Field and Property Values with Reflection

The nineteenth part of the Reflection tutorial expands upon the previous instalment that dealt with instantiating late-bound types. This article looks at the methods that allow reflected field and property values to be read and changed using reflection.

Setting Field Values

To change the values held in an object's fields we use the SetValue method from the FieldInfo class. This is almost identical to the PropertyInfo version. The difference is that fields cannot be indexed so no third parameter is required. In the following code the fields holding the Person's name are updated. The results are shown by outputting the value of the property that is based upon those fields.

NB: This example also demonstrates how you can access non-public members of classes. You should take care when using private fields and properties in this manner. As such members are not designed to be accessed, changes to their implementation would not be expected to impact external code. Reflection overcomes this boundary and you may find that your software is broken by such internal changes. You may also find that changing private variables has unexpected side-effects within the reflected types.

Type type = typeof(Person);
object lateBound = Activator.CreateInstance(type);
BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Instance;
        
FieldInfo firstNameField = type.GetField("_firstName", flags);
firstNameField.SetValue(lateBound, "Dan");

FieldInfo lastNameField = type.GetField("_lastName", flags);
lastNameField.SetValue(lateBound, "Green");

PropertyInfo fullNameProperty = type.GetProperty("FullName");
Console.WriteLine(fullNameProperty.GetValue(lateBound, null));

/* OUTPUT

Dan Green

*/

Reading Field Values

As you may expect, the FieldInfo class includes a GetValue method that returns the current value of a field. The object being queried is the only argument required. In the sample below, the first name field is first set before its value is read with GetValue.

Type type = typeof(Person);
object lateBound = Activator.CreateInstance(type);
BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Instance;

FieldInfo firstNameField = type.GetField("_firstName", flags);
firstNameField.SetValue(lateBound, "Ben");

Console.WriteLine(firstNameField.GetValue(lateBound));

/* OUTPUT

Ben

*/

Accessing Fields and Properties for Normal Object Instances

You can use the above methods of the PropertyInfo and FieldInfo classes on early-bound instances as well as late-bound objects. For most scenarios this is inadvisable, as you can often use the properties and fields directly, avoiding the performance penalties of reflection. However, when you must access non-public members, the reflection option is necessary.

The next sample shows how the value of the private "_firstName" field can be obtained from a normally instantiated Person instance.

Person person = new Person();
person.FirstName = "Jim";

BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Instance;
FieldInfo firstNameField = person.GetType().GetField("_firstName", flags);

string firstName = (string)firstNameField.GetValue(person);
Console.WriteLine(firstName);

Accessing Static Members

In addition to working with object instances, you can access static fields and properties to obtain or change their values. The same GetValue and SetValue methods are used for this purpose. The difference is that you do not need to provide an instance to work with. Instead, you set the instance argument to null.

To demonstrate, try running the following code, which outputs the value of the static, "_counter" field.

Type type = typeof(Person);
FieldInfo counterField = type.GetField("_counter");
Console.WriteLine(counterField.GetValue(null));
30 July 2012