You are previewing Programming F#.

Programming F#

Cover of Programming F# by Chris Smith Published by O'Reilly Media, Inc.

Dynamic Instantiation

In the previous section, you saw ways to examine types and reflect on their metadata. However, the real power of reflection lies in dynamic instantiation, which is a fancy way of saying “creating values at runtime whose type you didn’t know about at compile time.” In other words, given an instance of System.Type, create a new instance of the type it describes.

Instantiating Types

Dynamically instantiating types can be done using the Activator class. Example 12-6 defines a type PoliteWriter, and creates a new instance dynamically using Activator.CreateInstance.

The parameters to PoliteWriter’s constructor are passed in as an obj array. The result of CreateInstance is an obj, which will need to be cast as the type you want.

Example 12-6. Dynamic instantiation

> // Definte a polite text writer
open System.IO

type PoliteWriter(stream : TextWriter) =

    member this.WriteLine(msg : string) =
        sprintf "%s... please" msg
        |> stream.WriteLine;;

type PoliteWriter =
    new : stream:IO.TextWriter -> PoliteWriter
    member WriteLine : msg:string -> unit

> // Dynamically create an instance of that class
let politeConsole =
    Activator.CreateInstance(typeof<PoliteWriter>, [| box Console.Out |]);;

val politeConsole : obj

> (politeConsole :?> PoliteWriter).WriteLine("Hello, World!");;
Hello, World!... please
val it : unit = ()

Now you have the ability to not only load types but also to create new instances of them at runtime. This opens up powerful new capabilities for F# applications ...

The best content for your career. Discover unlimited learning on demand for around $1/day.