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.

Obtaining Information for Multiple Fields

In addition to retrieving data for individual fields you can get an array of FieldInfo objects relating to a number of fields from the same class. To retrieve all of the public fields, call GetFields with no arguments:

Type type = typeof(FieldTest);
FieldInfo[] info = type.GetFields();
foreach (FieldInfo field in info)
{
    Console.WriteLine(field.Name);
}

/* OUTPUT

PublicField
ReadOnlyField
StaticField

*/

You can also use binding flags with GetFields. This overloaded version retrieves all of the fields that match the provided binding flags. The code below uses the Public, NonPublic, Instance and Static flags to obtain details of every field in the FieldTest class:

Type type = typeof(FieldTest);
BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic |
    BindingFlags.Instance | BindingFlags.Static;
FieldInfo[] info = type.GetFields(flags);
foreach (FieldInfo field in info)
{
    Console.WriteLine(field.Name);
}

/* OUTPUT

PublicField
InternalField
ProtectedField
PrivateField
ProtectedInternalField
ReadOnlyField
StaticField
ConstantField

*/

Common FieldInfo Properties

There are a large number of properties and methods attached to the FieldInfo class to allow you to retrieve information about a field. In the final sections of this article you will see some of the more commonly used properties. To examine them and compare their values for several types of field, add the following code to the Main method of the project. This code obtains a FieldInfo object for each of the fields in the FieldTest class. The code samples that follow use this set of objects to demonstrate the properties.

Type type = typeof(FieldTest);
BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic |
    BindingFlags.Instance | BindingFlags.Static;
FieldInfo publicField = type.GetField("PublicField", flags);
FieldInfo internalField = type.GetField("InternalField", flags);
FieldInfo protectedField = type.GetField("ProtectedField", flags);
FieldInfo privateField = type.GetField("PrivateField", flags);
FieldInfo staticField = type.GetField("StaticField", flags);
FieldInfo protectedInternalField = type.GetField("ProtectedInternalField", flags);
FieldInfo readOnlyField = type.GetField("ReadOnlyField", flags);
FieldInfo constantField = type.GetField("ConstantField", flags);

Field Type Properties

There are four properties that can be used to determine information about the type of the field. The FieldType property returns a System.Type object describing to the field's data type. You can interrogate this further using the reflection techniques described in this tutorial. IsStatic returns a Boolean value. If true, the member is static. If false, it is an instance field. You can identify read-only fields, which can only have their values set during construction of an object, using the Boolean IsInitOnly property. Finally, the IsLiteral property is true for constants and false for variable fields.

The code below shows the output of these properties for some of the test class' fields.

Console.WriteLine(publicField.FieldType);

Console.WriteLine(staticField.IsStatic);
Console.WriteLine(readOnlyField.IsStatic);

Console.WriteLine(constantField.IsLiteral);
Console.WriteLine(staticField.IsLiteral);

Console.WriteLine(readOnlyField.IsInitOnly);
Console.WriteLine(internalField.IsInitOnly);

/* OUTPUT

System.String
True
False
True
False
True
False

*/

Scope Properties

A second group of properties can be used to determine the scope of fields. Each returns either true or false. The properties are:

  • IsAssembly. If true, this property indicates that the field is visible to all classes within its containing assembly and any friend assemblies. In C#, these are internal fields.
  • IsFamily. Specifies that a field is visible within the containing class and any subclasses. These are protected fields.
  • IsFamilyAndAssembly. Indicates that the field is visible within its class and any subclasses that reside within the same assembly. In C++, such fields are declared as protected private. C# does not support the creation of such members.
  • IsFamilyOrAssembly. These fields are visible within the containing class and any subclasses, as well as being available to any other class in the same assembly or a friend assembly. Such fields are declared as protected internal in C#.
  • IsPrivate. As you may expect, these fields are those declared as private. As such, they are visible only within their own class.
  • IsPublic. These are the fields with the widest possible scope, declare in C# as public. They are visible to any class in any assembly.
Console.WriteLine(internalField.IsAssembly);
Console.WriteLine(staticField.IsAssembly);

Console.WriteLine(protectedField.IsFamily);
Console.WriteLine(readOnlyField.IsFamily);

Console.WriteLine(protectedInternalField.IsFamilyOrAssembly);
Console.WriteLine(staticField.IsFamilyOrAssembly);

Console.WriteLine(privateField.IsPrivate);
Console.WriteLine(internalField.IsPrivate);

Console.WriteLine(publicField.IsPublic);
Console.WriteLine(internalField.IsPublic);

/* OUTPUT

True
False
True
False
True
False
True
False
True
False

*/
12 February 2012