在 C# 中创建 F# 区分联合类型
Creating F# discrimated union type in C#
我正在尝试将 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 问题,这些方法看起来应该默认可用。非常感谢任何关于为什么我缺少它们的指示。
您尝试做的不是 "discriminated union"。这是一个 不分青红皂白 的联盟。首先你创建了两种类型,然后你试图说:“第三种类型的值可能是这个或那个”。有些语言有不分青红皂白的联合(例如 TypeScript),但 F# 没有。
在 F# 中,您不能只说 "either this or that, go figure it out"。你需要给 union 的每个 case 一个 "tag"。识别它的东西。这就是为什么它被称为“discriminated”联合 - 因为您可以区分不同的情况。
例如:
type T = A of string | B of int
T
类型的值可能是 string
或 int
,要知道哪个值是看分配给它们的 "tags" - A
或 B
。
另一方面,以下在 F# 中是非法的:
type T = string | int
回到你的代码,为了"fix"它的机械方式,你需要做的就是添加区分大小写:
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");
我正在尝试将 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 问题,这些方法看起来应该默认可用。非常感谢任何关于为什么我缺少它们的指示。
您尝试做的不是 "discriminated union"。这是一个 不分青红皂白 的联盟。首先你创建了两种类型,然后你试图说:“第三种类型的值可能是这个或那个”。有些语言有不分青红皂白的联合(例如 TypeScript),但 F# 没有。
在 F# 中,您不能只说 "either this or that, go figure it out"。你需要给 union 的每个 case 一个 "tag"。识别它的东西。这就是为什么它被称为“discriminated”联合 - 因为您可以区分不同的情况。
例如:
type T = A of string | B of int
T
类型的值可能是 string
或 int
,要知道哪个值是看分配给它们的 "tags" - A
或 B
。
另一方面,以下在 F# 中是非法的:
type T = string | int
回到你的代码,为了"fix"它的机械方式,你需要做的就是添加区分大小写:
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");