假设我有这样的代码
let a = new List<int>()
let b = a :> obj :?> List<obj>
Run Code Online (Sandbox Code Playgroud)
它抛出一个异常,说它无法做到这一点,因为List<int>当我试图将其变成List<obj>. 我明白为什么这是一个问题。它不能神奇地为我创建一个用 obj 替换所有 int 类型的接口,但是我在这里能做什么呢?
我有一个对象,我知道它是一个列表。我如何访问元素而不关心它们的类型?
我的具体示例不使用列表,因此我需要一个通用的解决方案,而不是特定于列表的解决方案。
如果是列表,您可以使用它System.Collections.IList来访问元素
open System.Collections
open System.Collections.Generic
let x = List<int>()
let y: IList = downcast (x :> obj)
Run Code Online (Sandbox Code Playgroud)
这种方法也可以推广:让你的泛型类实现非泛型接口:
type IT =
abstract Value: obj
type T<'a>(a: 'a) =
member val Value = a;
interface IT with
member this.Value = upcast this.Value
Run Code Online (Sandbox Code Playgroud)
如果这不是一个选项(即因为您无法在类中进行更改),您可以随时诉诸反射
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|])
Run Code Online (Sandbox Code Playgroud)