Reputation: 4412
Say I have a code like this
let a = new List<int>()
let b = a :> obj :?> List<obj>
It throws an exception saying that it can't do it since one is List<int>
while I'm trying to make it an List<obj>
.
I understand why that's a problem. It can't just magically create an interface for me that replaces all int types with obj, but what CAN I do here?
I have an object and I know that's it's a List of something. How can I access the elements and just not care about their type?
My concrete example doesn't use Lists so I require a general, not a List specific, solution.
Upvotes: 4
Views: 654
Reputation: 16782
In case of lists you can use System.Collections.IList
to access elements
open System.Collections
open System.Collections.Generic
let x = List<int>()
let y: IList = downcast (x :> obj)
This approach can also be generalized: make your generic classes implement non-generic interface:
type IT =
abstract Value: obj
type T<'a>(a: 'a) =
member val Value = a;
interface IT with
member this.Value = upcast this.Value
If this is not an option (i.e. because you cannot make changes in classes) you can always resort to reflection
type T<'a>(a: 'a) =
member val Value = a;
type Action =
static member Do(a: T<_>) = printfn "%A" a.Value
let v = T(10)
let mi = typeof<Action>.GetMethod("Do").MakeGenericMethod(v.GetType().GetGenericArguments().[0])
mi.Invoke(null, [|v|])
Upvotes: 4