Partager via


Directives du compilateur

Cette rubrique décrit les directives du compilateur, pour les directives interactives F# (dotnet fsi), consultez Programmation interactive avec F#.

Une directive du compilateur est précédée du symbole # et apparaît sur une ligne par elle-même.

Le tableau suivant répertorie les directives du compilateur disponibles en F#.

Directive Description
#if if-expression Prend en charge la compilation conditionnelle. Code de la section après le #if est inclus si l' expression conditionnelle s'évalue à defined (voir ci-dessous).
#else Prend en charge la compilation conditionnelle. Marque une section de code à inclure si le symbole utilisé avec le précédent #if ne s'évalue pas à defined.
#endif Prend en charge la compilation conditionnelle. Marque la fin d'une section conditionnelle de code.
#[ligne] int,
#[ligne] chaîne int,
#[ligne] intverbatim-string
Indique la ligne et le nom de fichier du code source d'origine, à des fins de débogage. Cette fonctionnalité est fournie pour les outils qui génèrent du code source F#.
#nowarn warningcodes Désactive un ou plusieurs avertissements du compilateur, comme spécifié par les codes d’avertissement (voir ci-dessous).
#warnon warningcodes Active un ou plusieurs avertissements du compilateur, comme spécifié par les codes d’avertissement (voir ci-dessous).

Directives de compilation conditionnelle

Le code désactivé par l'une de ces directives apparaît en grisé dans l'éditeur de code de Visual Studio.

Le code suivant illustre l'utilisation des directives #if, #else et #endif. Dans cet exemple, le code contient deux versions de la définition de function1. Quand VERSION1 est défini à l'aide de l'option du compilateur -define, le code entre la directive #if et la directive #else est activé. Sinon, le code entre #else et #endif est activé.

#if VERSION1
let function1 x y =
   printfn "x: %d y: %d" x y
   x + 2 * y
#else
let function1 x y =
   printfn "x: %d y: %d" x y
   x - 2*y
#endif

let result = function1 10 20

La #if directive accepte également les expressions logiques :

#if SILVERLIGHT || COMPILED && (NETCOREFX || !DEBUG)
#endif

Les expressions suivantes peuvent être utilisées.

if-expr évaluation
if-expr1 \|\| if-expr2 defined si if-expr1 ou if-expr2 est defined.
if-expr1 && if-expr2 defined si if-expr1 et if-expr2 sont defined.
!if-expr1 defined si if-expr1 n’est pas defined.
( if-expr1 ) défini si if-expr1 est défini.
symbol defined s’il est marqué comme défini par l’option du -define compilateur.

Les opérateurs logiques ont la priorité logique habituelle.

Il n’existe aucune #define directive du compilateur en F#. Vous devez utiliser l'option du compilateur ou les paramètres du projet pour définir les symboles utilisés par la directive #if.

Les directives de compilation conditionnelle peuvent être imbriquées. La mise en retrait n’est pas significative pour les directives du compilateur.

Symboles prédéfinis

Le compilateur F# et le système de génération définissent automatiquement plusieurs symboles qui peuvent être utilisés pour la compilation conditionnelle.

Symboles de configuration de build

Les symboles suivants sont définis en fonction de votre configuration de build :

  • DEBUG: défini lors de la compilation en mode Débogage. Dans le système de projet, le DEBUG symbole est automatiquement défini dans la configuration de débogage, mais pas dans la configuration Release. Ce symbole est couramment utilisé avec des assertions et du code de diagnostic. Pour plus d’informations, consultez Assertions.
  • TRACE: défini pour les builds qui activent le suivi. Comme DEBUG, ce symbole est généralement défini dans les configurations de débogage, mais peut également être activé dans les configurations Release.

Vous pouvez remplacer ces valeurs à l’aide de l’option-define du compilateur ou des paramètres de projet.

Symboles du mode compilation

Les symboles suivants font la distinction entre différents modes de compilation :

  • COMPILED: défini lors de la compilation du code avec le compilateur F#. Ce symbole est utile lorsque vous avez besoin de code pour se comporter différemment dans les assemblys compilés et les sessions interactives F#.
  • INTERACTIVE: défini lors de la compilation ou de l’exécution de code dans F# Interactive (dotnet fsi), y compris les sessions interactives et l’exécution de script. Cela vous permet d’écrire du code qui fonctionne différemment lors de l’exécution interactive.

Pour plus d’informations sur l’utilisation de ces symboles dans des scripts, consultez Programmation interactive avec F#.

Exemple :

#if INTERACTIVE
// Code specific to F# Interactive
#r "nuget: Newtonsoft.Json"
#endif

#if COMPILED
// Code specific to compiled assemblies
open System.Configuration
#endif

Symboles de framework cible

Le système de génération définit également des symboles de préprocesseur pour différents frameworks cibles dans les projets de style SDK. Ces symboles sont utiles lors de la création de bibliothèques ou d’applications qui ciblent plusieurs versions de .NET.

Versions cibles de .NET Framework Symboles Symboles supplémentaires
(disponibles dans les SDK .NET 5+)
Symboles de plateforme (disponibles uniquement
lorsque vous spécifiez un TFM spécifique au système d’exploitation)
.NET Framework NETFRAMEWORK, NET481, NET48, NET472NET471NET47NET462NET461NET46NET452NET451NET45NET40NET35NET20 NET48_OR_GREATER, , NET472_OR_GREATER, NET47_OR_GREATERNET471_OR_GREATER, NET462_OR_GREATER, NET461_OR_GREATER, NET46_OR_GREATERNET452_OR_GREATERNET451_OR_GREATERNET45_OR_GREATERNET40_OR_GREATERNET35_OR_GREATERNET20_OR_GREATER
.NET Standard NETSTANDARD, , NETSTANDARD2_1, NETSTANDARD1_6NETSTANDARD2_0, , NETSTANDARD1_4NETSTANDARD1_1NETSTANDARD1_3NETSTANDARD1_2NETSTANDARD1_5NETSTANDARD1_0 NETSTANDARD2_1_OR_GREATER, NETSTANDARD2_0_OR_GREATER, , NETSTANDARD1_5_OR_GREATERNETSTANDARD1_6_OR_GREATER, NETSTANDARD1_4_OR_GREATER, NETSTANDARD1_3_OR_GREATER, NETSTANDARD1_2_OR_GREATER, NETSTANDARD1_1_OR_GREATER,NETSTANDARD1_0_OR_GREATER
.NET 5+ (et .NET Core) NET, NET10_0, NET9_0, NET8_0NET7_0NET6_0NET5_0NETCOREAPPNETCOREAPP3_1NETCOREAPP3_0NETCOREAPP2_2NETCOREAPP2_1NETCOREAPP2_0NETCOREAPP1_1NETCOREAPP1_0 NET10_0_OR_GREATER, , NET9_0_OR_GREATER, NET7_0_OR_GREATERNET8_0_OR_GREATER, NET6_0_OR_GREATER, NET5_0_OR_GREATER, NETCOREAPP3_1_OR_GREATERNETCOREAPP3_0_OR_GREATERNETCOREAPP2_2_OR_GREATERNETCOREAPP2_1_OR_GREATERNETCOREAPP2_0_OR_GREATERNETCOREAPP1_1_OR_GREATERNETCOREAPP1_0_OR_GREATER ANDROID, BROWSER, IOS, MACCATALYST, MACOS, TVOS, WINDOWS
[OS][version] (par exemple, IOS15_1),
[OS][version]_OR_GREATER (par exemple IOS15_1_OR_GREATER)

Note

  • Les symboles sans version sont définis indépendamment de la version que vous ciblez.
  • Les symboles spécifiques à la version sont définis uniquement pour la version que vous ciblez.
  • Les symboles <framework>_OR_GREATER sont définis pour la version que vous ciblez et toutes les versions antérieures. Par exemple, si vous ciblez .NET Framework 2.0, les symboles suivants sont définis : NET20, NET20_OR_GREATER, NET11_OR_GREATER et NET10_OR_GREATER.
  • Les symboles NETSTANDARD<x>_<y>_OR_GREATER sont définis uniquement pour les cibles .NET Standard, et non pour les cibles qui implémentent .NET Standard, telles que .NET Core et .NET Framework.
  • Ils sont différents des monikers de framework cible utilisés par la propriété MSBuild TargetFramework et NuGet.

Par exemple, vous pouvez utiliser ces symboles pour compiler du code de manière conditionnelle en fonction de l’infrastructure cible :

#if NET6_0_OR_GREATER
// Use .NET 6+ specific APIs
#else
// Use alternative implementation for older frameworks
#endif

Directive NULLABLE

À compter de F# 9, vous pouvez activer les types de référence nullables dans le projet :

<Nullable>enable</Nullable>

Cette opération définit automatiquement la directive NULLABLE sur le build. Il est utile, lors du déploiement initial de la fonctionnalité, de modifier conditionnellement le code en conflit à l'aide de directives de hachage #if NULLABLE.

#if NULLABLE 
let length (arg: 'T when 'T: not null) =
    Seq.length arg
#else
let length arg =
    match arg with
    | null -> -1
    | s -> Seq.length s
#endif

Directives de ligne

Lors de la génération, le compilateur signale les erreurs dans le code F# en référençant les numéros de ligne où chaque erreur se produit. Ces numéros de ligne commencent à 1 pour la première ligne dans un fichier. Toutefois, si vous générez du code source F# à partir d'un autre outil, les numéros de ligne du code généré n'ont en général aucun intérêt, car les erreurs dans le code F# généré proviennent très probablement d'une autre source. La directive #line offre un moyen aux auteurs d'outils qui génèrent du code source F# de transmettre des informations sur les numéros de ligne et fichiers sources d'origine au code F# généré.

Quand vous utilisez la directive #line, vous devez placer les noms de fichiers entre guillemets. À moins que le jeton textuel (@) ne s’affiche devant la chaîne, vous devez utiliser deux barres obliques inverses en tant que caractères d’espacement au lieu d’une pour les utiliser dans le chemin d’accès. Les jetons de ligne valides sont les suivants : Dans ces exemples, supposons que le fichier d'origine Script1 produit un fichier de code F# généré automatiquement quand il est exécuté par l'intermédiaire d'un outil et que le code situé à l'emplacement de ces directives est généré à partir de jetons à la ligne 25 du fichier Script1.

# 25
#line 25
#line 25 "C:\\Projects\\MyProject\\MyProject\\Script1"
#line 25 @"C:\Projects\MyProject\MyProject\Script1"
# 25 @"C:\Projects\MyProject\MyProject\Script1"

Ces jetons indiquent que le code F# généré à cet emplacement dérive de certaines constructions situées à ou près de la ligne 25 dans Script1.

Notez que les #line directives n’influencent pas le comportement de#nowarn / #warnon . Ces deux directives concernent toujours le fichier en cours de compilation.

Directives d’avertissement

Les directives d’avertissement désactivent ou activent les avertissements du compilateur spécifiés pour les parties d’un fichier source.

Une directive d’avertissement est une seule ligne de code source qui se compose de

  • Espace blanc facultatif
  • La chaîne #nowarn ou #warnon
  • Whitespace
  • Un ou plusieurs codes d’avertissement (voir ci-dessous), séparés par des espaces blancs
  • Espace blanc facultatif
  • Commentaire de ligne facultatif

Un code d’avertissement est une séquence de chiffres (représentant le numéro d’avertissement), éventuellement précédé de FS, éventuellement entouré de guillemets doubles.

Une #nowarn directive désactive un avertissement jusqu’à ce qu’une #warnon directive pour le même numéro d’avertissement soit trouvée, ou bien jusqu’à la fin du fichier. De même, une #nowarn directive désactive un avertissement jusqu’à ce qu’une #warnon directive pour le même numéro d’avertissement soit trouvée, ou bien jusqu’à la fin du fichier. Avant et après ces paires, la compilation par défaut s’applique, qui est

  • aucun avertissement s’il est désactivé par une option de compilateur --nowarn (ou la propriété msbuild respective)
  • aucun avertissement pour les avertissements à activation volontaire, sauf si activé par l'option du compilateur --warnon (ou la propriété MSBuild respective)

Voici un exemple (artificiel).

module A
match None with None -> ()     // warning
let x =
    #nowarn 25
    match None with None -> 1  // no warning
    #warnon FS25
match None with None -> ()     // warning
#nowarn "FS25" FS007 "42"
match None with None -> ()     // no warning

Voir aussi