Given a the .Net Type, say typeof<string>, at runtime how does one created the equivalent of string list = []?
My motivation is that when using FSharpValue.MakeRecord to create a record based on values parsed the values need to be passed as a obj[]. I've been up casting the arguments using box and that has worked except for with lists. The issue I've encountered is that a empty untyped list list can't be boxed and then unboxed. The specific error returned is: 
System.InvalidCastException: Unable to cast object of type 
'Microsoft.FSharp.Collections.FSharpList`1[System.Object]' 
to type 
'Microsoft.FSharp.Collections.FSharpList`1[System.String]'.
An empty typed list can be boxed and unboxed so I've tried to find a way to cast a list to a runtime type, e.g. a Type returned by typeof<> but with no luck.
type Test = {Names : string list}
// fails
let genericList = []
{Names = unbox (box genericList)}
//works
let typedList : string list = []
{Names = unbox (box typedList)}
//works
let genericNonEmptyList = ["Bill"]
{Names = unbox (box genericNonEmptyList)}
                You can create an empty list using an empty pair of square brackets [] or the type constructor list() , a built-in function that creates an empty list when no arguments are passed. Square brackets [] are commonly used in Python to create empty lists because it is faster and more concise.
To create an empty list, use [] for a growable list or List. empty for a fixed length list (or where growability is determined at run-time). The created list is fixed-length if length is provided. The list has length 0 and is growable if length is omitted.
Using reflection you can get the List module and call the generic empty method:
open System
open System.Reflection
let emptyList (t:Type) =
    Assembly.GetAssembly(typeof<_ list>)
        .GetType("Microsoft.FSharp.Collections.ListModule")
        .GetMethod("Empty", BindingFlags.Static ||| BindingFlags.Public)
        .MakeGenericMethod(t)
        .Invoke(null, [||])
use as follows:
let itemType = typeof<string>
let emptyStringList = emptyList(itemType) :?> string list
If you are calling that quite often, consider caching (reduces execution time by ~1/3):
let emptyList =
    let empty =
        Assembly.GetAssembly(typeof<_ list>)
            .GetType("Microsoft.FSharp.Collections.ListModule")
            .GetMethod("Empty", BindingFlags.Static ||| BindingFlags.Public)
    fun (t:Type) -> empty.MakeGenericMethod(t).Invoke(null, [||])
                        Let me add one more alternative answer - although both of the existing methods work, they rely on understanding how F# represents lists. In the first case, you need to know there is Empty method and in the second case, you need to know there is a union case called Empty. 
I generally prefer to do this by defining a helper type and using reflection over my custom type:
type ListHelper =
  static member Empty<'T>() : list<'T> = []
let makeEmpty =
  let empty = typeof<ListHelper>.GetMethod("Empty")
  let emptyArr : obj[] = [| |]
  fun ty -> empty.MakeGenericMethod([| ty |]).Invoke(null, emptyArr)
This gives you quite simple function that can cache the MethodInfo (you could even use Expression to pre-compile and cache the invocations) and does not rely on clever tricks. 
@CaringDev's answer using .NET reflection is fine, but you can also use the F#-specific reflection module to create instances of union cases:
let empty ty = 
    let uc = 
        Reflection.FSharpType.GetUnionCases(typedefof<_ list>.MakeGenericType [|ty|]) 
        |> Seq.filter (fun uc -> uc.Name = "Empty") 
        |> Seq.exactlyOne
    Reflection.FSharpValue.MakeUnion(uc, [||])
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With