F#泛型类型比较

6
我正在尝试确定从调用返回的对象是否属于特定类型。以下是我的代码:
type MyType<'T>= 
    val mutable myArr : array
    val mutable id : int
    val mutable value : 'T

在具有 "MyType" 范围的某些方法中...

let a  = someFunThatReturnsObj()   // a could be of type MyType 

我该如何确定a是否为MyType类型?

哦,运行时类型检查? 你知道你的方法返回什么类型吗? 如果是这样,也许你可以将类型封装在类型安全的联合类型中,并使用模式匹配来代替。也许你在该函数中的类型可以公开一个共同的接口?有很多方法可以避免运行时类型检查。 - Juliet
如果您不知道类型返回的是什么怎么办?如下所示,AS T1<T2<int>>与T1<T2<float>>不同,如果您只关心对象是否为T1而不考虑其他具体信息呢? - akaphenom
2个回答

6
match a with
| :? MyType<int> as mt -> // it's a MyType<int>, use 'mt'
| _ -> // it's not

如果你只关心一个未知的 XMyType<X>,那么

let t = a.GetType()
if t.IsGenericType && t.GetGenericTypeDefinition() = typedefof<MyType<int>> then
    // it is

看起来我又遇到了一个问题。似乎 someFunThatReturnsObj() 返回了 'U。使用您提供的第一种方法,我得到了以下错误信息:“此运行时强制转换或类型测试从类型 'U 到 MyType<int> 涉及基于此程序点之前的信息的不确定类型。某些类型不允许运行时类型测试。需要进一步的类型注释。” - PhilBrown
1
先调用“box”,然后执行“match box a with...”。 - Brian
我不确定你所说的“box”是什么意思,Brian? - PhilBrown
2
调用 box 函数,将其参数向上转换为 obj 类型。 - Brian

1

我认为这并不简单(请记住我对 F# 不熟悉),考虑以下场景:

1)我们正在多个类型上使用泛型 2)我们没有一个对象的类型信息,所以它作为类型 obj 进入函数中,例如在某些 .NET 数据合同 / 序列化库中

我重新设计了我的提案,使用反射:

type SomeType<'A> = { 
        item : 'A 
    } 


type AnotherType<'A> = { 
    someList : 'A list 
} 

let test() = 

    let getIt() : obj =  
        let results : SomeType<AnotherType<int>> = { item = { someList = [1;2;3] }} 
        upcast results 

    let doSomething (results : obj) =  
        let resultsType = results.GetType()
        if resultsType.GetGenericTypeDefinition() = typedefof<SomeType<_>> then 
            let method = resultsType.GetMethod("get_item")
            if method <> null then
                let arr = method.Invoke(results, [||]) 
                if arr.GetType().GetGenericTypeDefinition() = typedefof<AnotherType<_>> then 
                    printfn "match" 

    getIt() |> doSomething  

似乎应该有更自然的方法来做这件事...


这对于确定结果是否属于我所期望的SomeType<AnotherType<'T>>类别非常有用。但我仍然面临一个问题,即将结果强制转换并用作SomeType<AnotherType<System.Object>>。我可以控制'T'可能是什么。有人能否建议一种方法,例如使用所有对象'T'都可以使用的公共接口?或者使用一个公共超类? - PhilBrown

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接