这与我previous question关于以类型安全方式扩展第三方类型有关。有一些很好的答案,但它们依赖于编译时已知的具体类型。我不能依赖于此。有时类型是盒装的。有没有办法扩展第三方类型来模拟动态调度?
我会为自己的库使用接口。例如:
type ICanSerialize =
abstract ToSerializable : unit -> IDictionary<string,obj>
type B(items: obj[]) =
interface ICanSerialize with
member __.ToSerializable() =
dict ["Items", items |> Array.map (fun x ->
(x :?> ICanSerialize).ToSerializable()) |> box]
作为旁注,如果我们可以这样做会很好:
let inline toSerializable x =
(^T : (member ToSerializable : unit -> IDictionary<string,obj>) x)
let x = obj()
let d = toSerializable (unbox x)
但显然不可能将运行时强制转换和内联组合起来。
答案 0 :(得分:3)
如果我正确地理解了你的问题,你想要进行一些类似于强制转换的未知类型对象(System.Object
)的强制转换操作,并将其转换为某种结构类型,并且最好保证object支持此类型指定的所有操作。
我认为没有标准机制,但可以使用System.Reflection.
Emit
来实施。我为interoperability between C# and PHP some time ago实现了类似的功能。
我们的想法是编写一个动态生成实现接口的类的函数,并将接口的所有成员简单地委托给包装对象的成员。在包装对象时,您可以检查所有成员是否存在并具有正确的签名(但该对象实际上不必实现相同的接口)。
这对于代码示例来说有点太多代码,但我希望一般的想法也很有用(如果你想看看它是如何完成的话,请搜索Phalanger source code NewObject
方法)