Extensions de type (F#)
Les extensions de type vous permettent d'ajouter de nouveaux membres à un type d'objet précédemment défini.
// Intrinsic extension.
type typename with
member self-identifier.member-name =
body
...
[ end ]
// Optional extension.
type typename with
member self-identifier.member-name =
body
...
[ end ]
Notes
Il existe deux formes d'extensions de type. Celles-ci présentent une syntaxe et un comportement légèrement différents.Une extension intrinsèque est une extension qui figure dans le même espace de noms ou module, dans le même fichier source et dans le même assembly (DLL ou fichier exécutable) que le type qui est étendu.Une extension facultative est une extension qui figure à l'extérieur du module, de l'espace de noms ou de l'assembly d'origine du type qui est étendu.Les extensions intrinsèques apparaissent sur le type lorsque le type est examiné par réflexion, ce qui n'est pas le cas des extensions facultatives.Les extensions facultatives doivent se trouver dans des modules, et sont uniquement dans la portée lorsque le module qui contient l'extension est ouvert.
Dans la syntaxe précédente, typename représente le type qui est étendu.N'importe quel type accessible peut être étendu, mais le nom du type doit être un nom de type réel, et non une abréviation de type.Vous pouvez définir plusieurs membres dans une extension de type.self-identifier représente l'instance de l'objet qui est appelée, comme dans des membres ordinaires.
Le mot clé end est facultatif dans la syntaxe simplifiée.
Les membres définis dans des extensions de type peuvent être utilisés comme tout autre membre sur un type de classe.À l'instar d'autres membres, ils peuvent être statiques ou d'instance.Ces méthodes sont également appelées méthodes d'extension ; les propriétés sont appelées propriétés d'extension, etc.Les membres d'extension facultatifs sont compilés en membres statiques pour lesquels l'instance de l'objet est passée implicitement comme premier paramètre.Toutefois, ils se comportent comme s'ils étaient des membres d'instances ou des membres statiques selon la façon dont ils sont déclarés.Des membres d'extension implicites sont inclus comme membres du type et peuvent être utilisés sans restriction.
Les méthodes d'extension ne peuvent pas être des méthodes virtuelles ou abstraites.Elles peuvent surcharger d'autres méthodes du même nom, mais le compilateur donne la préférence aux méthodes de non-extension dans le cas d'un appel ambigu.
Si plusieurs extensions de type intrinsèques existent pour un type, tous les membres doivent être uniques.Pour les extensions de type facultatives, les membres dans différentes extensions de type du même type peuvent avoir les mêmes noms.Des erreurs d'ambiguïté se produisent uniquement si le code client ouvre deux portées différentes qui définissent les mêmes noms de membre.
Dans l'exemple suivant, un type dans un module a une extension de type intrinsèque.Pour le code client à l'extérieur du module, l'extension de type apparaît comme un membre standard du type à tous points de vue.
module MyModule1 =
// Define a type.
type MyClass() =
member this.F() = 100
// Define type extension.
type MyClass with
member this.G() = 200
module MyModule2 =
let function1 (obj1: MyModule1.MyClass) =
// Call an ordinary method.
printfn "%d" (obj1.F())
// Call the extension method.
printfn "%d" (obj1.G())
Vous pouvez utiliser des extensions de type intrinsèques pour séparer la définition d'un type en sections.Cela peut être utile pour la gestion de définitions de type importantes, par exemple pour conserver le code généré par le compilateur et le code créé séparés, ou pour grouper le code créé par des personnes différentes ou associé à différentes fonctionnalités.
Dans l'exemple suivant, une extension de type facultative étend le type System.Int32 avec une méthode d'extension FromString qui appelle le membre statique Parse.La méthode testFromString montre que le nouveau membre est appelé comme n'importe quel membre d'instance.
// Define a new member method FromString on the type Int32.
type System.Int32 with
member this.FromString( s : string ) =
System.Int32.Parse(s)
let testFromString str =
let mutable i = 0
// Use the extension method.
i <- i.FromString(str)
printfn "%d" i
testFromString "500"
Le nouveau membre d'instance apparaît comme toute autre méthode du type Int32 dans IntelliSense, mais uniquement lorsque le module contenant l'extension est ouvert ou dans la portée.