2017-02-22 89 views
-1

我试图将F#项目添加到我的C#解决方案中。我创建了一个F#项目并编写了一些F#代码,现在我正在尝试从我的C#项目中使用它。 我成功地引用了F#项目,并且可以访问它的类型,但存在区别联合的问题。例如,我有以下的F#中定义的类型:在C#中创建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问题,它看起来像这些方法应该默认可用。希望能够指出他们为什么错过我的任何指针。

回答

2

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

在F#中,你不能只说“这个或那个,去搞清楚”。你需要给联盟的每个案件一个“标签”。用来识别它的东西。这就是为什么它被称为“歧视”联盟 - 因为你可以区分这两种情况。

例如:

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"); 
+0

是的,你是正确的,我错过了一个“标签”。添加完成后,C#端的一切都运行良好。虽然非法类型T = string |的事实int编译成功并没有给我对F#的更多信心。 –

+0

你误会了。输入'T = string | int'不会编译。尝试一下。你所做的是一个没有数据的联合 - 基本上是一个枚举,就像'type T = A | B'。该枚举的标签恰好与前面定义的两个类型名称相同,但这并不违法,这很好,DU个案可以与类型名称冲突。 –

+0

好的谢谢澄清。 –