Delen via


Compilerrichtlijnen

In dit onderwerp worden compilerrichtlijnen beschreven, voor F# Interactive (dotnet fsi)-instructies, zie Interactive Programming met F#.

Een compiler-instructie wordt voorafgegaan door het #-symbool en wordt op een regel zelf weergegeven.

De volgende tabel bevat de compilerrichtlijnen die beschikbaar zijn in F#.

Directive Description
#if if-expression Ondersteunt voorwaardelijke compilatie. Code in het gedeelte na de #if wordt opgenomen als de if-expressie als defined geëvalueerd wordt (zie hieronder).
#else Ondersteunt voorwaardelijke compilatie. Markeert een codesectie die moet worden opgenomen als het symbool dat met de vorige #if is gebruikt, niet resulteert in defined.
#endif Ondersteunt voorwaardelijke compilatie. Hiermee wordt het einde van een voorwaardelijke sectie van de code gemarkeerd.
#[regel] int,
#[regel] int-tekenreeks,
#[regel] intverbatim-string
Geeft de oorspronkelijke broncoderegel en bestandsnaam aan voor foutopsporing. Deze functie is beschikbaar voor hulpprogramma's die F#-broncode genereren.
#nowarn waarschuwingscodes Hiermee schakelt u een of meer compilerwaarschuwingen uit zoals opgegeven door waarschuwingscodes (zie hieronder).
#warnon waarschuwingscodes Hiermee schakelt u een of meer compilerwaarschuwingen in zoals opgegeven door waarschuwingscodes (zie hieronder).

Richtlijnen voor voorwaardelijke compilatie

Code die door een van deze instructies is gedeactiveerd, wordt grijs weergegeven in de Visual Studio Code-editor.

De volgende code illustreert het gebruik van de #if, #elseen #endif instructies. In dit voorbeeld bevat de code twee versies van de definitie van function1. Wanneer VERSION1 wordt gedefinieerd met behulp van de optie -define compiler, wordt de code tussen de #if richtlijn en de #else richtlijn geactiveerd. Anders wordt de code tussen #else en #endif geactiveerd.

#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

De #if richtlijn accepteert ook logische expressies:

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

De volgende expressies kunnen worden gebruikt.

if-expr evaluation
if-expr1 \|\| if-expr2 defined als if-expr1 of if-expr2 is defined.
if-expr1 && if-expr2 defined als if-expr1 en if-expr2 zijn defined.
!if-expr1 defined als if-expr1 dat niet definedzo is.
( if-expr1 ) gedefinieerd als if-expr1 is gedefinieerd.
symbol defined als deze is gemarkeerd als gedefinieerd door de -define compileroptie.

De logische operators hebben de gebruikelijke logische prioriteit.

Er is geen #define compilerrichtlijn in F#. U moet de compileroptie of projectinstellingen gebruiken om de symbolen te definiëren die door de #if instructie worden gebruikt.

Voorwaardelijke compilatierichtlijnen kunnen worden genest. Inspringingen zijn niet van belang voor compilerrichtlijnen.

Vooraf gedefinieerde symbolen

De F#-compiler en het buildsysteem definiëren automatisch verschillende symbolen die kunnen worden gebruikt voor voorwaardelijke compilatie.

Configuratiesymbolen bouwen

De volgende symbolen worden gedefinieerd op basis van uw buildconfiguratie:

  • DEBUG: Gedefinieerd bij het compileren in de foutopsporingsmodus. In het projectsysteem wordt het DEBUG symbool automatisch gedefinieerd in de configuratie voor foutopsporing, maar niet in de releaseconfiguratie. Dit symbool wordt vaak gebruikt met asserties en diagnostische code. Zie Asserties voor meer informatie.
  • TRACE: Gedefinieerd voor builds die tracering inschakelen. Dit DEBUGsymbool wordt doorgaans gedefinieerd in configuraties voor foutopsporing, maar kan ook worden ingeschakeld in releaseconfiguraties.

U kunt deze waarden overschrijven met behulp van de -define compileroptie of projectinstellingen.

Symbolen in de compilatiemodus

De volgende symbolen maken onderscheid tussen verschillende compilatiemodi:

  • COMPILED: Gedefinieerd bij het compileren van code met de F#-compiler. Dit symbool is handig wanneer u code nodig hebt om zich anders te gedragen in gecompileerde assembly's versus F# Interactive-sessies.
  • INTERACTIVE: Gedefinieerd bij het compileren of uitvoeren van code in F# Interactive (dotnet fsi), inclusief interactieve sessies en het uitvoeren van scripts. Hiermee kunt u code schrijven die anders werkt wanneer u interactief werkt.

Zie Interactive Programming met F# voor meer informatie over het gebruik van deze symbolen in scripts.

Voorbeeld:

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

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

Symbolen van het doelframework

Het buildsysteem definieert ook preprocessorsymbolen voor verschillende doelframeworks in SDK-projecten. Deze symbolen zijn handig bij het maken van bibliotheken of toepassingen die gericht zijn op meerdere .NET-versies.

Doelplatformen Symbols Aanvullende symbolen
(beschikbaar in .NET 5+ SDK's)
Platformsymbolen (alleen beschikbaar)
wanneer u een besturingssysteemspecifieke TFM opgeeft)
.NET Framework NETFRAMEWORK, , NET481, , NET48, NET472, , NET471, NET47, NET462NET461NET46NET452NET451NET45NET40, NET35NET20 NET48_OR_GREATER, , NET472_OR_GREATER, , , , NET471_OR_GREATER, NET47_OR_GREATER, NET462_OR_GREATER, NET461_OR_GREATERNET46_OR_GREATERNET452_OR_GREATERNET451_OR_GREATERNET45_OR_GREATERNET40_OR_GREATERNET35_OR_GREATERNET20_OR_GREATER
.NET Standard NETSTANDARD, , NETSTANDARD2_1, NETSTANDARD2_0NETSTANDARD1_6, , NETSTANDARD1_5, NETSTANDARD1_4, , NETSTANDARD1_3NETSTANDARD1_2NETSTANDARD1_1NETSTANDARD1_0 NETSTANDARD2_1_OR_GREATER, , NETSTANDARD2_0_OR_GREATERNETSTANDARD1_6_OR_GREATER, NETSTANDARD1_5_OR_GREATER, , NETSTANDARD1_4_OR_GREATER, NETSTANDARD1_3_OR_GREATER, NETSTANDARD1_2_OR_GREATERNETSTANDARD1_1_OR_GREATERNETSTANDARD1_0_OR_GREATER
.NET 5+ (en .NET Core) NET, , NET10_0, , NET9_0, NET8_0, , NET7_0, NET6_0, NET5_0NETCOREAPPNETCOREAPP3_1NETCOREAPP3_0NETCOREAPP2_2NETCOREAPP2_1NETCOREAPP2_0, NETCOREAPP1_1NETCOREAPP1_0 NET10_0_OR_GREATER, , NET9_0_OR_GREATER, , , , NET8_0_OR_GREATER, NET7_0_OR_GREATER, NET6_0_OR_GREATER, NET5_0_OR_GREATERNETCOREAPP3_1_OR_GREATERNETCOREAPP3_0_OR_GREATERNETCOREAPP2_2_OR_GREATERNETCOREAPP2_1_OR_GREATERNETCOREAPP2_0_OR_GREATERNETCOREAPP1_1_OR_GREATERNETCOREAPP1_0_OR_GREATER ANDROID, , BROWSERIOS, MACCATALYST, , MACOS, , TVOSWINDOWS
[OS][version] (bijvoorbeeld IOS15_1),
[OS][version]_OR_GREATER (bijvoorbeeld IOS15_1_OR_GREATER)

Opmerking

  • Versieloze symbolen worden gedefinieerd, ongeacht op welke versie u zich richt.
  • Versiespecifieke symbolen worden alleen gedefinieerd voor de versie waarop u zich richt.
  • De <framework>_OR_GREATER symbolen worden gedefinieerd voor de versie waarop u zich richt en alle eerdere versies. Als u zich bijvoorbeeld richt op .NET Framework 2.0, worden de volgende symbolen gedefinieerd: NET20, NET20_OR_GREATER, NET11_OR_GREATERen NET10_OR_GREATER.
  • De NETSTANDARD<x>_<y>_OR_GREATER symbolen worden alleen gedefinieerd voor .NET Standard-doelen en niet voor doelen die .NET Standard implementeren, zoals .NET Core en .NET Framework.
  • Deze verschillen van de doelframework-monikers (TFM's) die worden gebruikt door de MSBuild TargetFramework-eigenschap en NuGet.

U kunt deze symbolen bijvoorbeeld gebruiken om code voorwaardelijk te compileren op basis van het doelframework:

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

NULLABLE-instructie

Vanaf F# 9 kunt u null-verwijzingstypen inschakelen in het project:

<Nullable>enable</Nullable>

Hiermee wordt de NULLABLE-directive automatisch ingesteld op de build. Het is handig wanneer u de functie in eerste instantie uitrolt om conflicterende code voorwaardelijk te wijzigen door #if NULLABLE hash-instructies:

#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

Regelrichtlijnen

Bij het bouwen rapporteert de compiler fouten in F#-code door te verwijzen naar regelnummers waarop elke fout optreedt. Deze regelnummers beginnen bij 1 voor de eerste regel in een bestand. Als u echter F#-broncode genereert vanuit een ander hulpprogramma, zijn de regelnummers in de gegenereerde code over het algemeen niet van belang, omdat de fouten in de gegenereerde F#-code waarschijnlijk ontstaan uit een andere bron. De #line richtlijn biedt een manier voor auteurs van hulpprogramma's die F#-broncode genereren om informatie over de oorspronkelijke regelnummers en bronbestanden door te geven aan de gegenereerde F#-code.

Wanneer u de #line instructie gebruikt, moeten bestandsnamen tussen aanhalingstekens staan. Tenzij het exacte token (@) voor de tekenreeks wordt weergegeven, moet u backslashtekens escapen door twee backslashtekens te gebruiken in plaats van één om ze in het pad te kunnen gebruiken. Hier volgen geldige regeltokens. In deze voorbeelden wordt ervan uitgegaan dat het oorspronkelijke bestand Script1 resulteert in een automatisch gegenereerd F#-codebestand wanneer het wordt uitgevoerd via een hulpprogramma en dat de code op de locatie van deze instructies wordt gegenereerd op basis van sommige tokens op regel 25 in het bestand Script1.

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

Deze tokens geven aan dat de F#-code die op deze locatie wordt gegenereerd, is afgeleid van een aantal constructies op of in de buurt van de regel 25 in Script1.

Houd er rekening mee dat #line richtlijnen geen invloed hebben op het gedrag van#nowarn / #warnon . Deze twee richtlijnen hebben altijd betrekking op het bestand dat wordt gecompileerd.

Instructies waarschuwen

Waarschuwingsrichtlijnen schakelen gespecificeerde compilerwaarschuwingen uit of in voor onderdelen van een bronbestand.

Een waarschuwingsrichtlijn is één regel broncode die bestaat uit

  • Optionele voorloopspaties
  • De tekenreeks #nowarn of #warnon
  • Whitespace
  • Een of meer waarschuwingscodes (zie hieronder), gescheiden door witruimte
  • Optionele witruimte
  • Optionele regelcommentaar

Een waarschuwingscode is een reeks cijfers (die het waarschuwingsnummer vertegenwoordigen), eventueel voorafgegaan door FS, eventueel omgeven door dubbele aanhalingstekens.

Een #nowarn instructie schakelt een waarschuwing uit totdat een #warnon instructie voor hetzelfde waarschuwingsnummer wordt gevonden, of anders tot het einde van het bestand. Op dezelfde manier wordt met een #nowarn richtlijn een waarschuwing uitgeschakeld totdat een #warnon richtlijn voor hetzelfde waarschuwingsnummer is gevonden, of tot het einde van het bestand. Voor en na dergelijke paren is de compilatiestandaard van toepassing. Dit is

  • geen waarschuwing indien uitgeschakeld door een --nowarn compiler-optie (of de respectieve msbuild-eigenschap)
  • geen waarschuwing voor opt-in-waarschuwingen, tenzij ingeschakeld door de compileroptie --warnon (of de betreffende MSBuild-eigenschap)

Hier volgt een (gekunsteld) voorbeeld.

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

Zie ook