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+

Reflecting Field Information

The third part of the Reflection tutorial looks at reflection of fields. Information about a type's fields can be obtained in FieldInfo objects, using System.Type class methods. FieldInfo objects include properties that describe a field's type and scope.

Fields

Fields are possibly the simplest members of a class so are a good starting point for an examination of the reflection of type members. Over the next few articles of this tutorial we'll expand the description of reflection of members to include properties, methods, constructors and other member types.

You can use reflection to obtain information about all of the fields in a class, including private, protected and internal fields that may otherwise not be available. In this article we will see how to obtain FieldInfo objects that are linked to fields and use the more common properties of this class to examine the field's type and scope. You can also use reflection to read the values from an object's fields and change those values, even if the field is private. This will be examined later in the tutorial.

To follow the code samples, create a new console application project. As we will be using types from the System.Reflection namespace, add the following using directive to your code:

using System.Reflection;

To show the use of reflection to examine fields we need a class with a number of fields, each declared differently. We'll use the following code:

public class FieldTest
{
    public string PublicField;
    internal string InternalField;
    protected string ProtectedField;
    private string PrivateField;
    public static string StaticField;
    protected internal string ProtectedInternalField;
    public readonly string ReadOnlyField;
    private const string ConstantField;
}

Obtaining Information for a Public Field

If you wish to examine a public field of a type you must first create a Type instance, then you can use the GetField method to obtain a FieldInfo object. The simplest overloaded version of the GetField method has a single parameter that receives a string. The string should contain the name of the field to be examined.

In the following sample code we start by creating a Type object for the FieldTest class, then use GetField to get a FieldInfo instance for the PublicField field. Note that the case of the field must be correct. If you misspell the field name or use the incorrect mix of upper and lower case, the method returns null. The final line of the example outputs the name of the field, which is held in the Name property of the FieldInfo class.

Type type = typeof(FieldTest);
FieldInfo info = type.GetField("PublicField");
Console.WriteLine(info.Name);

// Outputs "PublicField"

Obtaining Information for a Non-Public Field

The above overload of GetField cannot be used with non-public fields. If you try, you will find that the return value is null:

Type type = typeof(FieldTest);
FieldInfo info = type.GetField("PrivateField"); // null

In order to examine a non-public field you must use an alternative overload of GetField. This version still accepts the name of the field as the first argument. A second argument specifies the binding flags that you wish to use. Binding flags control which fields will be found when searching using GetField or other methods, including when reflecting other types of member. You set the binding flags with the BindingFlags enumeration. This includes a number of constants that allow you to specify whether you want to find instance or static fields and public or non-public members. The enumeration is decorated with the Flags attribute and allows you to combine flags using the logical OR operator. For example, you may combine several flags to search public and non-public instance fields only.

The following flags are useful when retrieving field information. There are other flags available so this list is not exhaustive.

  • Default. This constant is the default value for a BindingFlags value.
  • IgnoreCase. The IgnoreCase constant does not change the type of field that can be retrieved. It specifies that you wish to include fields where the case of the field name does not match that of the search term. This is useful if you control the reflection using information from a configuration file, where the user may not realise the importance of upper and lower case.
  • Instance. The Instance flag is used when you wish to include instance members in your search. You must include either this flag, the Static flag or both in order to achieve any results.
  • Static. The Static constant is used when you wish to include static members in your search.
  • Public. The Public flag is used when you wish to include public members in your search. You must include this, the NonPublic flag or both for a successful search.
  • NonPublic. The NonPublic constant is used when you wish to find non-public members, including internal, protected and private fields.

This means that in order to obtain information about the PrivateField field, we need to include the NonPublic and Instance flags, as shown below:

Type type = typeof(FieldTest);
FieldInfo info = type.GetField(
    "PrivateField", BindingFlags.NonPublic | BindingFlags.Instance);
Console.WriteLine(info.Name);

// Outputs "PrivateField"
12 February 2012