F Sharp Programming/Reflection

Reflection allows programmers to inspect types and invoke methods of objects at runtime without knowing their data type at compile time.

At first glance, reflection seems to go against the spirit of ML as it is inherently not type-safe, so typing errors using reflection are not discovered until runtime. However, .NET's typing philosophy is best stated as static typing where possible, dynamic typing when needed, where reflection serves to bring in the most desirable behaviors of dynamic typing into the static typing world. In fact, dynamic typing can be a huge time saver, often promotes the design of more expressive APIs, and allows code to be refactored much further than possible with static typing.

This section is intended as a cursory overview of reflection, not a comprehensive tutorial.

Inspecting Types
There are a variety of ways to inspect the type of an object. The most direct way is calling the  method (inherited from  ) on any non-null object:

Its also possible to get type information without an actual object using the built-in  method:

and  return an instance of , which has a variety of useful properties such as:
 * Returns the name of the type.
 * Returns the name of the type.


 * Returns an array of constructors defined on the type.
 * Returns an array of constructors defined on the type.


 * Returns an array of members defined on the type.
 * Returns an array of members defined on the type.


 * Invokes the specified member, using the specified binding constraints and matching the specified argument list
 * Invokes the specified member, using the specified binding constraints and matching the specified argument list

Example: Reading Properties
The following program will print out the properties of any object passed into it:

This program outputs the following:

--- Program+Car WheelCount: 4 Year: 2009 Model: Focus Make: Ford --- Program+Cat Name: Mittens Age: 3

Example: Setting Private Fields
In addition to discovering types, we can dynamically invoke methods and set properties:

Reflection is particularly remarkable in that it can read/write private fields, even on objects which appear to be immutable. In particular, we can explore and manipulate the underlying properties of an F# list: The example above mutates the list in place and to produce a circularly linked list. In .NET, "immutable" doesn't really mean immutable and private members are mostly an illusion.


 * Note: The power of reflection has definite security implications, but a full discussion of reflection security is far outside of the scope of this section. Readers are encouraged to visit the Security Considerations for Reflection article on MSDN for more information.

Microsoft.FSharp.Reflection Namespace
While .NET's built-in reflection API is useful, the F# compiler performs a lot of magic which makes built-in types like unions, tuples, functions, and other built-in types appear strange using vanilla reflection. The Microsoft.FSharp.Reflection namespace provides a wrapper for exploring F# types.

Using fsi:

Working With Attributes
.NET attributes and reflection go hand-in-hand. Attributes allow programmers to decorate classes, methods, members, and other source code with metadata used at runtime. Many .NET classes use attributes to annotate code in a variety of ways; it is only possible to access and interpret attributes through reflection. This section will provide a brief overview of attributes. Readers interested in a more complete overview are encouraged to read MSDN's Extending Metadata With Attributes series.

Attributes are defined using, a notation already seen in a variety of places in previous chapters of this book. The .NET framework includes a number of built-in attributes, including:


 * System.ObsoleteAttribute - used to mark source code intended to be removed in future versions.
 * System.FlagsAttribute - indicates that an enumeration can be treated as a bit field.
 * System.SerializableAttribute - indicates that class can be serialized.
 * System.Diagnostics.DebuggerStepThroughAttribute - indicates that the debugger should not step into a method unless it contains a break point.

We can create custom attributes by defining a new type which inherits from :

We can access attribute using reflection:

The  class has the side-effect of printing to the console on instantiation, demonstrating that   does not get constructed when instances of   are created.

Example: Encapsulating Singleton Design Pattern
Attributes are often used to decorate classes with any kind of ad-hoc functionality. For example, let's say we wanted to control whether single or multiple instances of classes are created based on an attribute:

This program outputs the following:

SingleOnly constructor NewAlways constructor NewAlways constructor x = x': true y = y': false

Using the attribute above, we've completely abstracted away the implementation details of the singleton design pattern, reducing it down to a single attribute. Its worth noting that the program above hard-codes a value of  or   into the attribute constructor; if we wanted to, we could pass a string representing a key from the application's config file and make class construction dependent on the config file.