将对象转换为泛型类型而不提供参数

Luk*_*vat 3 f#

假设我有这样的代码

let a = new List<int>()
let b = a :> obj :?> List<obj>
Run Code Online (Sandbox Code Playgroud)

它抛出一个异常,说它无法做到这一点,因为List<int>当我试图将其变成List<obj>. 我明白为什么这是一个问题。它不能神奇地为我创建一个用 obj 替换所有 int 类型的接口,但是我在这里能做什么呢?

我有一个对象,我知道它是一个列表。我如何访问元素而不关心它们的类型?

我的具体示例不使用列表,因此我需要一个通用的解决方案,而不是特定于列表的解决方案。

des*_*sco 5

如果是列表,您可以使用它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)