Classe, structure
Classe
Classe en F♯ ≡ classe en C♯
Brique de base pour l'orienté-objet
Constructeur d'objets contenant des données de type défini et des méthodes
Définition d'une classe
Commence par
type(comme tout type en F♯)Nom de la classe généralement suivi du constructeur primaire
type CustomerName(firstName: string, lastName: string) =
// Corps du constructeur primaire
// Membres...☝ Paramètres firstName et lastName visibles dans tout le corps de la classe
Classe générique
Paramètres génériques à spécifier car non inférés
type Tuple2_KO(item1, item2) = // ⚠️ 'item1' et 'item2': type 'obj' !
// ...
type Tuple2<'T1, 'T2>(item1: 'T1, item2: 'T2) = // 👌
// ...Constructeur secondaire
Syntaxe pour définir un autre constructeur : new(argument-list) = constructor-body
☝ Doit appeler le constructeur primaire !
☝ Paramètres des constructeurs : que en tuple, pas curryfiés !
Instanciation
Appel d'un des constructeurs, avec arguments en tuple
Ne pas oublier
()si aucun argument, sinon on obtient une fonction !
Dans un let binding : new optionnel et non recommandé
let v = Vector(1.0, 2.0)👌let v = new Vector(1.0, 2.0)❌
Dans un use binding : new obligatoire
use d = new Disposable()
Initialisation des propriétés
On peut initialiser des propriétés avec setter à l'instanciation
Les spécifier en tant que arguments nommés dans l'appel au constructeur
Les placer après les éventuels arguments du constructeur :
💡 Équivalent de la syntaxe C♯ new PersonName("John") { Last = "Paul" }
Classe vide
Pour définir une classe sans corps, on utilise la syntaxe verbeuse class end :
Singleton
On peut définir une classe Singleton en rendant privé le constructeur primaire :
⚠️ Pas thread safe !
💡 On peut utiliser simplement une single-case union :
Classe abstraite
Annotée avec [<AbstractClass>]
Un des membres est abstrait :
Déclaré avec mot clé
abstractPas d'implémentation par défaut avec mot clé
default(Sinon le membre est virtuel)
Héritage via mot clé inherit, suivi de l'appel au constructeur de la classe de base
Exemple :
Champs
Convention de nommage : camelCase
2 types de champs : implicite ou explicite
Implicite ≃ Variable à l'intérieur du constructeur primaire
Explicite ≡ Champ classique d'une classe en C♯ / Java
Champ implicite
Syntaxe :
Variable :
[static] let [ mutable ] variable-name = expressionFonction :
[static] let [ rec ] function-name function-args = expression
☝ Notes
Déclaré avant les membres de la classe
Valeur initiale obligatoire
Privé
S'utilise sans devoir préfixer par le
self-identifier
D'instance
Statique
Champ explicite
Déclaration du type, sans valeur initiale : val [ mutable ] [ access-modifier ] field-name : type-name
val mutable a: int→ champ publiqueval a: int→ champ internea@+ propriétéa => a@
Champ vs propriété
Champ explicite ou implicite ou propriété
Champ explicite peu utilisé :
Ne concerne que les classes et structures
Utile avec fonction native manipulant la mémoire directement (Car ordre des champs préservés - cf. SharpLab)
Besoin d'une variable
[<ThreadStatic>]Interaction avec classe F♯ de code généré sans constructeur primaire
Champ implicite - let binding
Variable intermédiaire lors de la construction
Autres cas d'usages → propriété auto-implémentée
Exposer une valeur →
member valExposer un "champ" mutable →
member val ... with get, set
Structures
Alternatives aux classes mais + limités / héritage et récursivité
Même syntaxe que pour les classes mais avec en plus :
Soit attribut
[<Struct>]Soit bloc
struct...end(fréquent)
Mis à jour
Ce contenu vous a-t-il été utile ?