2017-02-22 3 views
-1

J'essaie d'ajouter un projet F # à ma solution C#. J'ai créé un projet F # et j'ai écrit du code F #, maintenant j'essaie de l'utiliser depuis mes projets C#. J'ai réussi à référencer le projet F # et j'ai accès à ses types, mais j'ai des problèmes avec les syndicats discriminés. Par exemple, je suis suivant les types définis dans F #:Création d'un type d'union F # discrimée en C#

namespace Sample 

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

Je peux créer un objet NotificationReceiverUser directement comme suit:

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

, mais je dois NotificationReceiver objet, et je ne reçois pas NotificationReceiver.NewNotificationReceiverUser ou Méthodes statiques NotificationReceiver.NewNotificationReceiverGroup. En regardant d'autres questions SO, il semble que ces méthodes devraient être disponibles par défaut. Apprécierait n'importe quel pointeur sur pourquoi ils me manquent.

Répondre

2

Ce que vous essayez de faire n'est pas une "union discriminée". C'est indiscrimée union. D'abord vous avez créé deux types, et puis vous essayez de dire: "les valeurs de ce troisième type peuvent être ceci ou cela". Certaines langues ont des unions indiscriminées (par exemple TypeScript), mais pas F #. En F #, vous ne pouvez pas simplement dire "ceci ou cela, allez-y". Vous devez donner une "étiquette" à chaque cas de l'union. Quelque chose par lequel le reconnaître. C'est pourquoi on l'appelle un syndicat "discriminé" - parce que vous pouvez faire la distinction entre les cas.

Par exemple:

type T = A of string | B of int 

Les valeurs de type T peuvent être soit string ou int, et la façon de savoir que l'on est de regarder les « tags » qui leur sont assignées - A ou B respectivement.

qui suit, d'autre part, est illégale en F #:

type T = string | int 

Pour revenir à votre code, afin de « réparer » la manière mécanique, tout ce que vous devez faire est d'ajouter cas discriminateurs :

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

Mais mon intuition me dire que ce que vous réellement voulait faire était la suivante:

type NotificationReceiver = 
    | NotificationReceiverUser of string 
    | NotificatonReceiverGroup of string 

Deux cas du même type (bizarre, mais légal), toujours distingués par des tags.

Avec une telle définition, vous y accéder à partir de C# ainsi:

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

Oui, vous avez raison, je manque un « tag ». Après l'avoir ajouté, tout a bien fonctionné côté C#. Bien que le type illégal T = string | int compiles avec succès ne me donne pas beaucoup de confiance en F #. –

+0

Vous vous méprenez. Tapez 'T = chaîne | int' ne compilerait pas. Essayez-le. Qu'est-ce que vous avez fait était une union sans données - essentiellement une énumération, comme le type T = A | B'. Les étiquettes de cette énumération ont été nommées de manière identique aux deux types précédemment définis, mais ce n'est pas illégal, c'est bien, les cas de DU sont autorisés à entrer en conflit avec les noms de types. –

+0

Ok merci pour clarifier cela. –