在C#中创建F#discrimated union类型

时间:2017-02-22 13:00:27

标签: c#-to-f#

我试图将F#项目添加到我的C#解决方案中。我创建了一个F#项目并编写了一些F#代码,现在我试图在我的C#项目中使用它。 我成功引用了F#项目并可以访问它的类型,但是遇到了歧视联盟的问题。例如,我在F#中定义了以下类型:

namespace Sample

type NotificationReceiverUser = NotificationReceiverUser of string
type NotificationReceiverGroup = NotificationReceiverGroup of string
type NotificationReceiver = NotificationReceiverUser | NotificatonReceiverGroup

我可以直接创建NotificationReceiverUser对象,如下所示:

var receiver = NotificationReceiverUser.NewNotificationReceiverUser("abc");

,但我需要NotificationReceiver对象,而且我没有得到NotificationReceiver.NewNotificationReceiverUser或NotificationReceiver.NewNotificationReceiverGroup静态方法。看看其他一些SO问题,看起来默认情况下这些方法应该可用。非常感谢任何有关他们为什么缺席的指示。

1 个答案:

答案 0 :(得分:3)

你要做的不是“受歧视的联盟”。这是一个 indiscrimnated 联盟。首先你创建了两种类型,然后你试图说:“这第三种类型的值可能是这个或那个”。有些语言有不加区别的联盟(例如TypeScript),但F#没有。

在F#中,你不能只是说“无论是这个还是那个,去弄清楚”。你需要给联盟的每个案例一个“标签”。识别它的东西。这就是为什么它被称为“受歧视的”联盟 - 因为你可以区分这些案件。

例如:

type T = A of string | B of int

T类型的值可以是stringint,以及了解分配给它们的“标记”的方式 - A或分别为B

另一方面,以下内容在F#中是非法的:

type T = string | int

回到你的代码,为了用机械方式“修复”它,你需要做的就是添加案例鉴别器:

type NotificationReceiverUser = NotificationReceiverUser of string
type NotificationReceiverGroup = NotificationReceiverGroup of string
type NotificationReceiver = A of NotificationReceiverUser | B of NotificatonReceiverGroup

但我的直觉告诉我,你实际的意图是:

type NotificationReceiver = 
   | NotificationReceiverUser of string 
   | NotificatonReceiverGroup of string

两个相同类型的案例(奇怪但合法)仍然以标签区分。

通过这样的定义,您可以从C#访问它:

var receiver = NotificationReceiver.NewNotificationReceiverUser("abc");