Compartir vía


Directivas del compilador

En este tema se describen las directivas del compilador para las directivas interactivas (dotnet fsi) de F#, consulte Programación interactiva con F#.

Una directiva del compilador tiene como prefijo el símbolo # y aparece en una línea por sí misma.

En la tabla siguiente se enumeran las directivas del compilador que están disponibles en F#.

Directive Description
#if if-expression Admite la compilación condicional. Código en la sección después de #if se incluye si la expresión if se evalúa a defined (ver más abajo).
#else Admite la compilación condicional. Marca una sección de código que se va a incluir si el símbolo usado con el anterior #if no se evalúa como defined.
#endif Admite la compilación condicional. Marca el final de una sección condicional de código.
#[línea] int,
#[línea] intstring,
#[línea] intverbatim-string
Indica el nombre de archivo y la línea de código fuente original para la depuración. Esta característica se proporciona para las herramientas que generan código fuente de F#.
#nowarn códigos de advertencia Deshabilita una o varias advertencias del compilador según lo especificado por los códigos de advertencia (consulte a continuación).
#warnon códigos de advertencia Habilita una o varias advertencias del compilador, tal como se especifican mediante códigos de advertencia (consulte a continuación).

Directivas de compilación condicional

El código que se desactiva mediante una de estas directivas aparece atenuado en el editor de Visual Studio Code.

El siguiente código muestra el uso de las directivas #if, #else y #endif. En este ejemplo, el código contiene dos versiones de la definición de function1. Cuando VERSION1 se define mediante la opción de compilador -define, se activa el código entre la directiva #if y la directiva #else. De lo contrario, se activará el código entre #else y #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 directiva también acepta expresiones lógicas:

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

Se pueden usar las expresiones siguientes.

if-expr evaluación
if-expr1 \|\| if-expr2 defined si if-expr1 o if-expr2 es defined.
if-expr1 && if-expr2 defined si if-expr1 y if-expr2 son defined.
!if-expr1 defined si if-expr1 no defined es.
( if-expr1 ) está definido si if-expr1 está definido.
symbol defined si se marca como se define en la -define opción del compilador.

Los operadores lógicos tienen la prioridad lógica habitual.

No hay ninguna #define directiva del compilador en F#. Hay que usar la configuración del proyecto o la opción del compilador pertinente para definir los símbolos que la directiva #if usa.

Las directivas de compilación condicional se pueden anidar. La sangría no es significativa para las directivas del compilador.

Símbolos predefinidos

El compilador de F# y el sistema de compilación definen automáticamente varios símbolos que se pueden usar para la compilación condicional.

Símbolos de configuración de compilación

Los símbolos siguientes se definen en función de la configuración de compilación:

  • DEBUG: se define al compilar en modo de depuración. En el sistema del proyecto, el DEBUG símbolo se define automáticamente en la configuración de depuración, pero no en la configuración de versión. Este símbolo se usa normalmente con aserciones y código de diagnóstico. Para obtener más información, vea Aserciones.
  • TRACE: se define para compilaciones que habilitan el seguimiento. Al igual que DEBUG, este símbolo se define normalmente en configuraciones de depuración, pero también se puede habilitar en configuraciones de versión.

Puede invalidar estos valores mediante la opción del compilador o la-define configuración del proyecto.

Símbolos del modo de compilación

Los símbolos siguientes distinguen entre diferentes modos de compilación:

  • COMPILED: se define al compilar código con el compilador de F#. Este símbolo es útil cuando se necesita código para comportarse de forma diferente en ensamblados compilados frente a sesiones interactivas de F#.
  • INTERACTIVE: se define al compilar o ejecutar código en F# Interactive (dotnet fsi), incluidas las sesiones interactivas y la ejecución de scripts. Esto le permite escribir código que funciona de forma diferente al ejecutarse de forma interactiva.

Para obtener más información sobre el uso de estos símbolos en scripts, vea Programación interactiva con F#.

Ejemplo:

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

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

Símbolos de la plataforma de destino

El sistema de compilación también define símbolos de preprocesador para diferentes marcos de destino en proyectos de estilo SDK. Estos símbolos son útiles al crear bibliotecas o aplicaciones destinadas a varias versiones de .NET.

Versiones de .NET Framework de destino Símbolos Símbolos adicionales
(disponible en SDK de .NET 5+)
Símbolos de plataforma (solo disponibles
cuando se especifica un TFM específico del sistema operativo)
.NET Framework NETFRAMEWORK, NET481, NET48, NET472, , NET471NET47, NET462, NET461, NET46NET452NET451NET45NET40NET35NET20 NET48_OR_GREATER, NET472_OR_GREATER, NET471_OR_GREATER, NET47_OR_GREATER, , NET461_OR_GREATERNET462_OR_GREATER, NET46_OR_GREATER, NET452_OR_GREATERNET451_OR_GREATERNET45_OR_GREATERNET40_OR_GREATERNET35_OR_GREATERNET20_OR_GREATER
.NET Standard NETSTANDARD, NETSTANDARD2_1, NETSTANDARD2_0, NETSTANDARD1_6, NETSTANDARD1_5, NETSTANDARD1_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_GREATER, NETSTANDARD1_3_OR_GREATER, NETSTANDARD1_2_OR_GREATER, NETSTANDARD1_1_OR_GREATERNETSTANDARD1_0_OR_GREATER
.NET 5+ (y .NET Core) NET, NET10_0, NET9_0, NET8_0, , NET7_0NET6_0, NET5_0, NETCOREAPP, NETCOREAPP3_1NETCOREAPP3_0NETCOREAPP2_2NETCOREAPP2_1NETCOREAPP2_0NETCOREAPP1_1NETCOREAPP1_0 NET10_0_OR_GREATER, NET9_0_OR_GREATER, NET8_0_OR_GREATER, NET7_0_OR_GREATER, , NET5_0_OR_GREATERNET6_0_OR_GREATER, NETCOREAPP3_1_OR_GREATER, NETCOREAPP3_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] (por ejemplo IOS15_1),
[OS][version]_OR_GREATER (por ejemplo, IOS15_1_OR_GREATER)

Nota:

  • Los símbolos sin versión se definen independientemente de la versión a la que apuntas.
  • Los símbolos específicos de la versión solo se definen para la versión de destino.
  • Los símbolos <framework>_OR_GREATER se definen para la versión de destino y todas las versiones anteriores. Por ejemplo, si tiene como destino .NET Framework 2.0, se definen los símbolos siguientes: NET20, NET20_OR_GREATER, NET11_OR_GREATER y NET10_OR_GREATER.
  • Los símbolos NETSTANDARD<x>_<y>_OR_GREATER solo se definen para destinos de .NET Standard y no para destinos que implementan .NET Standard, como .NET Core y .NET Framework.
  • Son diferentes de los monikers de la plataforma de destino (TFM) que usa la propiedad MSBuildTargetFramework y NuGet.

Por ejemplo, puede usar estos símbolos para compilar código condicionalmente en función del marco de destino:

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

Directiva NULLABLE

A partir de F# 9, puede habilitar tipos de referencia que aceptan valores NULL en el proyecto:

<Nullable>enable</Nullable>

Esto establece automáticamente la directiva NULLABLE en la compilación. Es útil, al implementar inicialmente la funcionalidad, cambiar condicionalmente el código en conflicto mediante directivas 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

Directivas de línea

Al compilar, el compilador informa de los posibles errores en el código de F# haciendo referencia a los números de línea en los que cada error se produce. Estos números de línea empiezan por 1 en la primera línea en un archivo. Pero si genera código fuente de F# con otra herramienta, los números de línea en el código generado no suelen ser de interés, ya que lo más probable es que los errores en el código de F# generado provengan de otro código fuente. La directiva #line constituye una forma de que los creadores de herramientas que generan código fuente de F# pasen información sobre los archivos de origen y los números de línea originales al código de F# generado.

Cuando se usa la directiva #line, es necesario que los nombres de archivo estén entre comillas. A menos que el token textual (@) aparezca delante de la cadena, hay que anteponer caracteres de barra diagonal inversa usando dos caracteres de barra diagonal inversa en lugar de uno, ya que así se podrán usar en la ruta de acceso. Los siguientes tokens de línea son válidos. En estos ejemplos, se da por hecho que el archivo original Script1 da como resultado un archivo de código de F# generado automáticamente cuando se ejecuta con una herramienta y, asimismo, que el código en la ubicación de estas directivas se genera a partir de determinados tokens en la línea 25 del archivo Script1.

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

Estos tokens indican que el código de F# generado en esta ubicación se deriva de algunas construcciones en la línea 25 en Script1, o cerca de ella.

Tenga en cuenta que #linelas directivas no influyen en el comportamiento de #nowarn / #warnon. Estas dos directivas siempre relacionan el archivo que se está compilando.

Directivas de advertencia

Las directivas de advertencia deshabilitan o habilitan las advertencias del compilador especificadas para partes de un archivo de origen.

Una directiva de advertencia es una sola línea de código fuente que consta de

  • Espacio en blanco inicial opcional
  • #nowarn Cadena o#warnon
  • Whitespace
  • Uno o más códigos de advertencia (consulte a continuación), separados por espacios en blanco
  • Espacio en blanco opcional
  • Comentario de línea opcional

Un código de advertencia es una secuencia de dígitos (que representa el número de advertencia), precedido opcionalmente por FS, rodeado opcionalmente por comillas dobles.

Una #nowarn directiva deshabilita una advertencia hasta que se encuentra una #warnon directiva para el mismo número de advertencia, o bien hasta el final del archivo. De forma similar, una #nowarn directiva deshabilita una advertencia hasta que se encuentre una #warnon directiva para el mismo número de advertencia, o bien hasta el final del archivo. Antes y después de estos pares, se aplica el valor predeterminado de compilación, que es

  • no hay ninguna advertencia si está deshabilitada por una opción del compilador --nowarn (o la propiedad msbuild correspondiente)
  • no hay ninguna advertencia para advertencias opcionales, a menos que esté habilitada por la opción del compilador --warnon (o la propiedad msbuild correspondiente)

Este es un ejemplo (forzado).

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

Consulte también