【问题标题】:Creating F# discrimated union type in C#在 C# 中创建 F# 区分联合类型
【发布时间】:2017-02-22 13:00:27
【问题描述】:

我正在尝试将 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 问题,这些方法似乎默认情况下应该可用。非常感谢任何关于他们为什么对我失踪的指示。

【问题讨论】:

    标签: c#-to-f#


    【解决方案1】:

    您尝试做的不是“歧视性工会”。这是一个不分青红皂白的工会。首先,您创建了两种类型,然后您试图说:“第三种类型的值可能是这个或那个”。一些语言有不分青红皂白的联合(例如TypeScript),但 F# 没有。

    在 F# 中,您不能只说“要么这个要么那个,去弄清楚”。您需要给联合的每个案例一个“标签”。识别它的东西。这就是为什么它被称为“discriminated”联合 - 因为您可以区分不同的情况。

    例如:

    type T = A of string | B of int
    

    T 类型的值可以是 stringint,而知道哪一个的方法是查看分配给它们的“标签” - 分别是 AB

    另一方面,以下内容在 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");
    

    【讨论】:

    • 是的,你是对的,我错过了一个“标签”。添加后,C# 端一切正常。虽然非法类型 T = string | int 编译成功并没有让我对 F# 充满信心。
    • 你误会了。类型 T = string | int 不会编译。试试看。你所做的是一个没有数据的联合——基本上是一个枚举,比如type T = A | B。该枚举的标签恰好与之前定义的两个类型的名称相同,但这并不违法,这很好,DU 案例允许与类型名称冲突。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-04
    • 1970-01-01
    • 2020-08-22
    • 2017-11-18
    • 2013-06-21
    相关资源
    最近更新 更多