F#中泛型类型的运行时强制

ham*_*ett 5 .net f#

我在F#中有一个带有显式泛型参数的基类.我正在尝试检查我使用的给定类型是否实现了特定的接口.我想"如果ob:?ISysAware那么"会做,但抱怨总是一样的:

let (|SysAware|_|) t = 
    match t with
    | :? ISysAware as p -> Some(p)
    | _ -> None
Run Code Online (Sandbox Code Playgroud)

错误FS0008:从类型'a到ISysAware的此运行时强制或类型测试涉及基于此程序点之前的信息的不确定类型.某些类型不允许运行时类型测试.需要进一步的类型注释.

显然,我宁愿不在这里使用反射.IsAssignableFrom会以高成本完成这个任务.

思考?

pad*_*pad 14

一些F#类型是值类型; 添加box确保仅对引用类型执行类型测试:

let (|SysAware|_|) t = 
    match box t with
    | :? ISysAware as p -> Some(p)
    | _ -> None
Run Code Online (Sandbox Code Playgroud)

  • 有趣,但我确实有 'a : not struct 和 'a : null 作为约束。 (2认同)

Joh*_*mer 5

错误的原因是类型检查器被混淆,因为它无法解决类型,解决方案 - 类似于pad是添加类型注释

let (|SysAware|_|) (t:obj) = 
    match t with
    | :? ISysAware as p -> Some(p)
    | _ -> None
Run Code Online (Sandbox Code Playgroud)