Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Questo argomento descrive le direttive del compilatore, per le direttive F# Interactive (dotnet fsi), vedere Programmazione interattiva con F#.
Una direttiva del compilatore è preceduta dal simbolo # e viene visualizzata su una riga in modo autonomo.
Nella tabella seguente sono elencate le direttive del compilatore disponibili in F#.
| Directive | Description |
|---|---|
#if
if-expression |
Supporta la compilazione condizionale. Il codice nella sezione successiva a #if è incluso se l'if-expression viene valutata come defined (vedere di seguito). |
#else |
Supporta la compilazione condizionale. Contrassegna una sezione di codice da includere se il simbolo usato con il precedente #if non restituisce defined. |
#endif |
Supporta la compilazione condizionale. Contrassegna la fine di una sezione condizionale di codice. |
#[riga] int,#[riga] intstring,#[riga] intverbatim-string |
Indica la riga e il nome di file del codice sorgente originale per il debug. Questa funzionalità viene fornita per gli strumenti che generano codice sorgente F#. |
#nowarn
warningcodes |
Disabilita uno o più avvisi del compilatore come specificato da warningcodes (vedere di seguito). |
#warnon
warningcodes |
Abilita uno o più avvisi del compilatore come specificato dai codici di avviso (vedere di seguito). |
Direttive di compilazione condizionale
Il codice disattivato da una di queste direttive viene visualizzato in grigio nell'editor di Visual Studio Code.
Nel codice di esempio che segue viene illustrato l'uso delle direttive #if, #else e #endif. In questo esempio, il codice contiene due versioni della definizione di function1. Quando VERSION1 viene definito usando l'opzione del compilatore -define, viene attivato il codice tra la #if direttiva e la #else direttiva . In caso contrario, viene attivato il codice tra #else e #endif.
#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 direttiva accetta anche espressioni logiche:
#if SILVERLIGHT || COMPILED && (NETCOREFX || !DEBUG)
#endif
È possibile usare le espressioni seguenti.
| if-expr | evaluation |
|---|---|
if-expr1 \|\| if-expr2 |
defined se if-expr1 o if-expr2 è defined. |
if-expr1 && if-expr2 |
defined se if-expr1 e if-expr2 sono defined. |
!if-expr1 |
defined se if-expr1 non è defined. |
( if-expr1 ) |
definito se if-expr1 è definito. |
symbol |
defined se è contrassegnato come definito dall'opzione del -define compilatore. |
Gli operatori logici hanno la consueta precedenza logica.
Non esiste alcuna #define direttiva del compilatore in F#. È necessario usare l'opzione del compilatore o le impostazioni di progetto per definire i simboli usati per la direttiva #if.
Le direttive di compilazione condizionale possono essere annidate. Il rientro non influenza le direttive del compilatore.
Simboli predefiniti
Il compilatore F# e il sistema di compilazione definiscono automaticamente diversi simboli che possono essere usati per la compilazione condizionale.
Simboli di configurazione della compilazione
I simboli seguenti vengono definiti in base alla configurazione di compilazione:
-
DEBUG: definito durante la compilazione in modalità debug. Nel sistema del progetto ilDEBUGsimbolo viene definito automaticamente nella configurazione debug, ma non nella configurazione release. Questo simbolo viene comunemente usato con asserzioni e codice di diagnostica. Per altre informazioni, vedere Asserzioni. -
TRACE: definito per le compilazioni che abilitano la traccia. ComeDEBUG, questo simbolo viene in genere definito nelle configurazioni di debug, ma può essere abilitato anche nelle configurazioni di rilascio.
È possibile eseguire l'override di questi valori usando l'opzione del compilatore o le impostazioni del-define progetto.
Simboli della modalità di compilazione
I simboli seguenti distinguono tra diverse modalità di compilazione:
-
COMPILED: definito durante la compilazione del codice con il compilatore F#. Questo simbolo è utile quando è necessario che il codice si comporti in modo diverso negli assembly compilati rispetto alle sessioni interattive F#. -
INTERACTIVE: definito durante la compilazione o l'esecuzione di codice in F# Interactive (dotnet fsi), incluse le sessioni interattive e l'esecuzione di script. In questo modo è possibile scrivere codice che funziona in modo diverso quando si esegue in modo interattivo.
Per altre informazioni sull'uso di questi simboli negli script, vedere Programmazione interattiva con F#.
Esempio:
#if INTERACTIVE
// Code specific to F# Interactive
#r "nuget: Newtonsoft.Json"
#endif
#if COMPILED
// Code specific to compiled assemblies
open System.Configuration
#endif
Simboli del framework di destinazione
Il sistema di compilazione definisce anche i simboli del preprocessore per framework di destinazione diversi nei progetti in stile SDK. Questi simboli sono utili quando si creano librerie o applicazioni destinate a più versioni .NET.
| Framework di destinazione | Simboli | Simboli aggiuntivi (disponibile in .NET 5+ SDK) |
Simboli della piattaforma (disponibile solo quando si specifica un TFM specifico del sistema operativo) |
|---|---|---|---|
| .NET Framework |
NETFRAMEWORK, , , , NET481NET48NET472NET471NET47NET462NET461NET46NET452NET451NET45NET40NET35NET20 |
NET48_OR_GREATER
NET471_OR_GREATER, NET472_OR_GREATER, NET47_OR_GREATER, NET462_OR_GREATER, NET461_OR_GREATER, NET46_OR_GREATER, NET452_OR_GREATERNET451_OR_GREATER, , NET45_OR_GREATERNET40_OR_GREATER, , NET35_OR_GREATERNET20_OR_GREATER |
|
| .NET Standard |
NETSTANDARD
NETSTANDARD2_0, NETSTANDARD2_1, , NETSTANDARD1_6, NETSTANDARD1_5NETSTANDARD1_4, NETSTANDARD1_3, NETSTANDARD1_2, , NETSTANDARD1_1NETSTANDARD1_0 |
NETSTANDARD2_1_OR_GREATER, NETSTANDARD2_0_OR_GREATER, NETSTANDARD1_6_OR_GREATER, NETSTANDARD1_5_OR_GREATER, NETSTANDARD1_4_OR_GREATERNETSTANDARD1_3_OR_GREATER, NETSTANDARD1_2_OR_GREATER, , NETSTANDARD1_1_OR_GREATERNETSTANDARD1_0_OR_GREATER |
|
| .NET 5+ (e .NET Core) |
NET, , , , NET10_0NET9_0NET8_0NET7_0NET6_0NET5_0NETCOREAPPNETCOREAPP3_1NETCOREAPP3_0NETCOREAPP2_2NETCOREAPP2_1NETCOREAPP2_0NETCOREAPP1_1NETCOREAPP1_0 |
NET10_0_OR_GREATER
NET8_0_OR_GREATER, NET9_0_OR_GREATER, NET7_0_OR_GREATER, NET6_0_OR_GREATER, NET5_0_OR_GREATER, NETCOREAPP3_1_OR_GREATER, NETCOREAPP3_0_OR_GREATERNETCOREAPP2_2_OR_GREATER, , NETCOREAPP2_1_OR_GREATERNETCOREAPP2_0_OR_GREATER, , NETCOREAPP1_1_OR_GREATERNETCOREAPP1_0_OR_GREATER |
ANDROID, BROWSER, IOS, MACCATALYST, MACOS, TVOS, WINDOWS[OS][version] (ad esempio IOS15_1),[OS][version]_OR_GREATER (ad esempio, IOS15_1_OR_GREATER) |
Annotazioni
- I simboli senza versione vengono definiti indipendentemente dalla versione di destinazione.
- I simboli specifici della versione sono definiti solo per la versione di destinazione.
- I simboli
<framework>_OR_GREATERsono definiti per la versione di destinazione e per tutte le versioni precedenti. Ad esempio, se si ha come destinazione .NET Framework 2.0, vengono definiti i simboli seguenti:NET20,NET20_OR_GREATER,NET11_OR_GREATEReNET10_OR_GREATER. - I simboli
NETSTANDARD<x>_<y>_OR_GREATERsono definiti solo per le destinazioni .NET Standard e non per le destinazioni che implementano .NET Standard, ad esempio .NET Core e .NET Framework. - Questi sono diversi dai moniker del framework di destinazione (TFMs) usati dalla proprietà
TargetFrameworkMSBuild e da NuGet.
Ad esempio, è possibile usare questi simboli per compilare in modo condizionale il codice in base al framework di destinazione:
#if NET6_0_OR_GREATER
// Use .NET 6+ specific APIs
#else
// Use alternative implementation for older frameworks
#endif
Direttiva NULLABLE
A partire da F# 9, è possibile abilitare i tipi di riferimento nullable nel progetto.
<Nullable>enable</Nullable>
In questo modo, la direttiva NULLABLE viene impostata automaticamente nella compilazione. Per modificare in modo condizionale il codice in conflitto durante l'implementazione iniziale della funzionalità, è utile utilizzare le direttive hash #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
Direttive Line
Durante la compilazione, il compilatore segnala errori nel codice F# facendo riferimento ai numeri di riga in cui si verifica ogni errore. Questi numeri di riga iniziano da 1 per la prima riga in un file. Tuttavia, se si genera codice sorgente F# da un altro strumento, i numeri di riga nel codice generato non sono generalmente di interesse, perché nel codice F# generato probabilmente gli errori sono causati da un'altra origine. La direttiva #line consente agli autori di strumenti che generano codice sorgente F# di passare le informazioni relative ai numeri di riga e ai file di origine originali al codice F# generato.
Quando si usa la direttiva #line, i nomi di file devono essere racchiusi tra virgolette. A meno che il token verbatim (@) venga visualizzato all'inizio della stringa, è necessario eseguire l'escape dei caratteri barra rovesciata usando due barre rovesciate anziché una per poterli usare nel percorso. Di seguito sono riportati dei token di riga validi. In questi esempi si presuppone che il file originale Script1 risulti in un file di codice F# generato automaticamente quando viene eseguito tramite uno strumento e che il codice nella posizione di tali direttive venga generato dagli stessi token alla riga 25 nel file Script1.
# 25
#line 25
#line 25 "C:\\Projects\\MyProject\\MyProject\\Script1"
#line 25 @"C:\Projects\MyProject\MyProject\Script1"
# 25 @"C:\Projects\MyProject\MyProject\Script1"
Questi token indicano che il codice F# generato in questa posizione è derivato da alcuni costrutti alla riga o vicino alla riga 25 in Script1.
Si noti che #line le direttive non influiscono sul comportamento di#nowarn / #warnon . Queste due direttive riguardano sempre il file che viene compilato.
Direttive Di avviso
Le direttive Warn disabilitano o abilitano gli avvisi del compilatore specificati per parti di un file di origine.
Una direttiva di avviso è una singola riga di codice sorgente costituita da
- Spazi vuoti iniziali facoltativi
- Stringa
#nowarno#warnon - Whitespace
- Uno o più codici di avviso (vedere di seguito), separati da spazi vuoti
- Spazi vuoti facoltativi
- Commento riga facoltativo
Un warningcode è una sequenza di cifre (che rappresenta il numero di avviso), facoltativamente preceduto da FS, racchiuso facoltativamente tra virgolette doppie.
Una #nowarn direttiva disabilita un avviso fino a quando non viene trovata una #warnon direttiva per lo stesso numero di avviso oppure fino alla fine del file. Analogamente, una #nowarn direttiva disabilita un avviso finché non viene trovata una #warnon direttiva per lo stesso numero di avviso oppure fino alla fine del file. Prima e dopo tali coppie, viene applicata l'impostazione predefinita di compilazione, ovvero
- nessun avviso se disabilitato da un'opzione del compilatore --nowarn (o la rispettiva proprietà msbuild)
- nessun avviso per gli avvisi di consenso, a meno che non sia abilitato dall'opzione del compilatore --warnon (o dalla rispettiva proprietà msbuild)
Di seguito è riportato un esempio artificiale.
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