F # discriminé syndicats contre C # hiérarchies de classes
-
27-10-2019 - |
Question
Je le code suivant:
public abstract class A ...
public class B : A ...
public class C : A ...
void my_fct(A x) {
if (x is B) { block_1 }
else if (x is C) { block_2 }
else { block_3 }
}
et je me demande si elle est une bonne traduction de F #
type a = B | C
let my_fct x =
match x with
| B -> ( block_1 )
| C -> ( block_2 )
| _ -> ( block_3 )
??
La solution
F # discriminé syndicats correspondent à des hiérarchies de classe OO très près, donc c'est probablement la meilleure option. La plus grande différence notable est que vous ne pouvez pas ajouter de nouveaux cas à une union discriminée sans modifier la déclaration de type. D'autre part, vous pouvez facilement ajouter de nouvelles fonctions qui fonctionnent avec le type (ce qui correspond à peu près à l'ajout de nouvelles méthodes virtuelles en C #).
Donc, si vous ne vous attendez pas à ajouter de nouvelles classes héritées (cas), alors c'est la meilleure option. Dans le cas contraire, vous pouvez utiliser F # types d'objets (ou d'autres options, en fonction du scénario).
Un autre point concernant votre code - puisque vous ne pouvez pas ajouter de nouveaux cas, F # compilateur sait que les seuls cas dont vous avez besoin sont pour B
et C
. En conséquence, l'block_3
ne peut jamais être exécuté, ce qui signifie que vous pouvez écrire simplement:
let my_fct x =
match x with
| B -> ( block_1 )
| C -> ( block_2 )
Autres conseils
oui ce qui est plus ou moins la même chose que F # ne importe comment. Dans ce cas (pas de valeurs ajoutées) - F # semble traduire en une Classs pour « un » et quelques mots clés (énumération). La classe « a » a seulement une propriété statique pour B et C, et quelques méthodes pour vérifier si un objet de type « a » est « B » ou « C » (voir ci-dessous)
Mais vous n'avez pas besoin. « _ -> (block_3) » cas, parce que cela ne peut jamais être égalé (F # sait tous les cas possibles et vous mettre en garde)
Je pense qu'il vaut mieux si vous jetez une exception en C # pour ce cas « else ».