2

这与我之前关于以类型安全的方式扩展第三方类型的问题有关。有一些很好的答案,但它们依赖于编译时已知的具体类型。我不能依赖这个。有时类型是盒装的。有没有办法扩展第三方类型来模拟动态调度?

我会为我自己的库使用一个接口。例如:

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)

但显然不可能将运行时强制转换和内联结合起来。

4

1 回答 1

3

如果我正确理解您的问题,您希望进行一些类似转换的操作,该操作采用未知类型 ( System.Object) 的动态加载对象并将其转换为某种结构类型,并且最好保证该对象支持由指定的所有操作这个类型。

我认为没有标准机制,但可以使用System.Reflection. Emit. 不久前,我为 C# 和 PHP 之间的互操作性实现了类似的东西。

这个想法是编写一个函数来动态生成一个实现接口的类,并且接口的所有成员都简单地委托给包装对象的成员。在包装对象时,您可以检查所有成员是否存在并具有正确的签名(但对象实际上不必实现相同的接口)。

对于代码示例来说,这有点太多了,但我希望总体思路也很有用(如果您想了解它是如何完成的,请在Phalanger 源代码中搜索方法)。NewObject

于 2012-04-05T16:43:52.270 回答