Generics F#ICastableTo<';T>;相等的

Generics F#ICastableTo<';T>;相等的,generics,interface,casting,f#,Generics,Interface,Casting,F#,不能在F#中实现通用接口的多个实例。在我的例子中,这是一个令人沮丧的问题,因为我计划实现一个名为ICastableTo的接口= /// ///返回对象的强制转换版本 /// 成员。值:'T ... (*x:obj*) 将x与 | :? ICastableTo as x->doSomethingWith(x.Value) |->invalidOp(“不能那样施展”) 然而,当我尝试实际使用它时,我面临一个问题,因为我无法实现多版本的ICastableTo接口(请参阅),但我的一些类实际上可以

不能在F#中实现通用接口的多个实例。在我的例子中,这是一个令人沮丧的问题,因为我计划实现一个名为ICastableTo的接口= /// ///返回对象的强制转换版本 /// 成员。值:'T ... (*x:obj*) 将x与 | :? ICastableTo as x->doSomethingWith(x.Value) |->invalidOp(“不能那样施展”) 然而,当我尝试实际使用它时,我面临一个问题,因为我无法实现多版本的ICastableTo接口(请参阅),但我的一些类实际上可以转换为多个类型

我最好的选择是什么?当然,我可以定义一个ICastable接口,并使用一个“possibleCast”属性,该属性将公开所有可用的铸造代理,但这并不是非常漂亮,也不能很好地处理继承


我的代码是这样的:

type BindableFunction<'T,'V>(func : 'T -> 'V) =
    member val Parent : 'T = nothing with get, set
    interface Specializable with
        member SpecializeFor(x: obj) =
            match x with | :? ICastable<'T> as x -> Parent <- x.Value | _ -> invalidOp("")
类型BindableFunction(func:'T->'V)=
成员val Parent:'T=不包含get,set
专用于
成员(x:obj)=

将x与|::匹配?最后,我采用了以下方法:

type BindableFunction<'T,'V>(convert: obj -> 'T, func : 'T -> 'V) =
    member val Parent : 'T = nothing with get, set
    interface Specializable with
        member SpecializeFor(x: obj) =
            match x with 
            | :? 'T as x -> (Parent <- x) 
            | _          -> (Parent <- convert(x))
最后:

new BindableFunction<Cell,_>(!CastToCell,...)
newbindablefunction(!CastToCell,…)

一个简单的问题,为什么在这里你的
x
参数和
对象
不是一个泛型类型?例如,参数
x
实际上不是一个
对象
,但它的类型不能转换为
某个类型
(即使在运行时也是如此)。换句话说,它是一个继承自
x
类型的类,定义了到
SomeType
的转换,而不是直接继承
x
类型。要正确使用“匹配:?”模式,您必须将对象框起来,因为另一个F#限制,但这与此处无关。通过将转换代码与您的类型分开怎么样?@Daniel是的,这是一个好主意,实际上,如果没有更好的解决方案,我可能会这样做。目前,我有一个类似的想法,即使用Reflection.Emit在运行时基于当前实现ICastableTo的已知类型属性动态构建类型转换器,但实际创建一个泛型转换函数并在那里执行工作并非不可行。这仍然没有我想的那么优雅,但这正变得越来越近,谢谢。@FremyCompany:静态类型系统中的类型转换本质上是不优雅的。如果您可以提供关于用例的更多细节,也许还可以提供一些类型定义,那么其他的解决方案可能会变得显而易见。
let CastToCell = ref(fun(o:obj) -> match o with | :? ICellScope as o -> o.ICell.Cell | _ -> invalidOp("invalid scope conversion"))
new BindableFunction<Cell,_>(!CastToCell,...)