3

我正在研究System.ComponentModel.Composition在 Fsharp 中使用,并想知道是否可以在内存中动态生成一个有区别的联合?我想要 DU 是基于导入的类型的元素构建的。主要原因是我有一个 DU 的代码,我认为使用它最简单Composition。我完全准备好接受这是错误的做法。

过去我用过FSharpTypeFSharpValue做各种事情,但似乎这些都是关于操纵现有的 DU 而不是创建新的 DU。

很抱歉,我什至还没有“我试过这个”代码示例,因为我不知道从哪里开始。

  • 可能吗?
  • 可取吗?
  • 我真的应该使用 DU 来表示来自 Composition 的内容吗?
  • 我很高兴使用反射,即使它有点慢。

编辑

  • 是否可以/建议动态添加到 DU?(如果必须存在 DU)
4

1 回答 1

4

可区分联合的一大优点是可能的情况集在编译时是已知的,因此编译器可以告诉您代码何时无法处理可能的情况。这对重构有很大帮助,因为您可以将新案例添加到现有联合中,编译器会告诉您代码中的哪些地方需要更改。

另一个好处是可区分联合上的模式匹配在语法上很优雅——您可以编写非常清晰的代码。

从理论上讲,您可能可以使用 Reflection.emit 动态生成 DU,或者甚至可以将新案例添加到现有案例中。然而,上述任何一个优点都不会适用,所以我根本看不出使用它们有多大意义。

标准继承模型也是处理动态加载插件的正确方法,IMO。在每个插件依赖的 DLL 中定义一个接口或公共基类,让插件定义一个实现它的类,然后在加载后在插件上使用该接口/基类上的方法。

DU 旨在提前修复可能的 /values/ 集合,但使任何人都可以轻松地在 DU 上编写新函数,而面向对象的继承旨在提前修复可能的基本 /functions/ 集合,但使任何人都可以轻松添加新值。由于动态加载代码就是添加新值,我认为这是一种非常自然的方式。

顺便提一下,DU 实际上是由 F# 编译器使用 .NET 继承实现的——整个联合类型都有一个基类,然后是每个联合案例的单独派生类(尽管我认为无参数案例会得到特殊处理) .

于 2013-10-06T15:39:57.743 回答