Compartir a través de


Conversiones (F#)

En este tema se describe la compatibilidad con las conversiones de tipos de F#.

Tipos aritméticos

F# proporciona operadores de conversión para conversiones aritméticas entre varios tipos primitivos; por ejemplo, entre los tipos enteros y de punto flotante.Los operadores de conversión de los tipos enteros y char tienen formas comprobadas y no comprobadas; pero los operadores de punto flotante y el operador de conversión enum no las tienen.Las formas no comprobadas se definen en y Microsoft.FSharp.Core.Operators, y las comprobadas, en Microsoft.FSharp.Core.Operators.Checked.Las formas comprobadas comprueban el desbordamiento y generan una excepción en tiempo de ejecución si el valor resultante supera los límites del tipo de destino.

Cada uno de estos operadores tiene el mismo nombre que el tipo de destino.Por ejemplo, en el código siguiente, en que los tipos se anotan explícitamente, byte aparece con dos significados diferentes.La primera aparición es el tipo y la segunda, el operador de conversión.

let x : int = 5

let b : byte = byte x

En la siguiente tabla, se muestran los operadores de conversión definidos en F#.

Operador

Descripción

byte

Realiza la conversión en byte, un tipo de 8 bits sin signo.

sbyte

Realiza la conversión en byte con signo.

int16

Realiza la conversión en un entero de 16 bits con signo.

uint16

Realiza la conversión en un entero de 16 bits sin signo.

int32, int

Realiza la conversión en un entero de 32 bits con signo.

uint32

Realiza la conversión en un entero de 32 bits sin signo.

int64

Realiza la conversión en un entero de 64 bits con signo.

uint64

Realiza la conversión en un entero de 64 bits sin signo.

nativeint

Realiza la conversión en un entero nativo.

unativeint

Realiza la conversión en un entero nativo sin signo.

float, double

Realiza la conversión en un número de 64 bits de punto flotante IEEE de precisión doble.

float32, single

Realiza la conversión en un número de 32 bits de punto flotante IEEE de precisión sencilla.

decimal

Realiza la conversión en System.Decimal.

char

Realiza la conversión en System.Char, un carácter Unicode.

enum

Realiza la conversión en un tipo enumerado.

Además de los tipos primitivos integrados, se pueden utilizar estos operadores con tipos que implementan los métodos op_Implicit u op_Explicit con las signaturas apropiadas.Por ejemplo, el operador de conversión int se puede usar con cualquier tipo que proporcione un método op_Explicit estático que tome el tipo como parámetro y devuelva int.Como excepción especial a la regla general de que los métodos no se pueden sobrecargar con el tipo de valor devuelto, sí se puede hacerlo para op_Explicit y op_Implicit.

Tipos enumerados

El operador enum es un operador genérico que toma un parámetro de tipo que representa el tipo de enum en el que se debe convertir.Cuando se convierte en un tipo enumerado, la inferencia de tipos intenta determinar el tipo de enum en el que se desea convertir.En el ejemplo siguiente, la variable col1 no está anotada explícitamente, pero su tipo se deduce a partir del la prueba de igualdad posterior.Por consiguiente, el compilador puede deducir que se va a convertir en una enumeración Color.Como alternativa, se puede proporcionar una anotación de tipo, como sucede con col2 en el ejemplo siguiente.

type Color =
    | Red = 1
    | Green = 2
    | Blue = 3

// The target type of the conversion is determined by type inference.
let col1 = enum 1
// The target type is supplied by a type annotation.
let col2 : Color = enum 2 
do
    if (col1 = Color.Red) then
       printfn "Red"

También puede especificar el tipo de enumeración de destino explícitamente como parámetro de tipo, como en el código siguiente:

let col3 = enum<Color> 3

Observe que funcionan las conversiones de enumeración sólo si el tipo de enumeración es compatible con el tipo que se va a convertir.En el código siguiente, la conversión no se compila por falta de coincidencia entre int32 y uint32.

// Error: types are incompatible
let col4 : Color = enum 2u

Para obtener más información, vea Enumeraciones (F#).

Convertir tipos de objeto

La conversión entre tipos de una jerarquía de objetos es fundamental para la programación orientada a objetos.Hay dos tipos básicos de conversiones: la conversión en tipos superiores (conversión hacia arriba) y la conversión en tipos inferiores (conversión hacia abajo).Convertir en los tipos superiores de una jerarquía significa convertir desde una referencia a objeto derivada a una referencia a objeto base.Este tipo de conversión de tipos funcionará seguro siempre que la clase base se encuentre en la jerarquía de herencia de la clase derivada.La conversión en tipos inferiores de una jerarquía, desde una referencia a objeto base a una referencia a objeto derivada, únicamente funciona si el objeto es, en realidad, una instancia del tipo de destino (derivado) correcto o un tipo derivado del tipo de destino.

F# proporciona operadores para estos tipos de conversiones.El operador :> convierte en tipos superiores de la jerarquía; :?>, en tipos inferiores de la jerarquía.

Dd233220.collapse_all(es-es,VS.110).gifConvertir hacia arriba

En muchos lenguajes orientados a objetos, la conversión hacia arriba está implícita; en F#, las reglas son ligeramente diferentes.La conversión hacia arriba se aplica automáticamente al pasar argumentos a métodos para un tipo de objeto.Sin embargo, para las funciones enlazadas mediante let de un módulo, la conversión hacia arriba no es automática a no ser que el tipo de parámetro se declare como tipo flexible.Para obtener más información, vea Tipos flexibles (F#).

El operador :> realiza una conversión de tipos estática, lo que significa que su validez se determina en tiempo de compilación.Si una conversión de tipos que utiliza :> se compila correctamente, es una conversión de tipos válida y no existe ninguna posibilidad de error en tiempo de ejecución.

También se puede utilizar el operador upcast para realizar este tipo de conversión.La expresión siguiente especifica una conversión en tipos superiores de la jerarquía.

upcast expression

Cuando se utiliza el operador de conversión hacia arriba, el compilador intenta realizar la inferencia a partir del contexto del tipo en el que se convierte.Si el compilador no puede determinar el tipo de destino, notifica un error.

Dd233220.collapse_all(es-es,VS.110).gifConvertir hacia abajo

El operador :?> realiza una conversión de tipos dinámica, lo que significa que la validez de la conversión de tipos se determina en tiempo de ejecución.Una conversión que utiliza el operador :?> no se comprueba en tiempo de compilación; sin embargo, en tiempo de ejecución se intenta realizar la conversión al tipo especificado.Si el objeto es compatible con el tipo de destino, la conversión se realiza correctamente.En caso contrario, el runtime inicia InvalidCastException.

También se puede utilizar el operador downcast para realizar una conversión de tipos dinámica.La expresión siguiente especifica una conversión en un tipo inferior de la jerarquía que se deduce a partir del contexto del programa.

downcast expression

Igual que sucede con el operador de conversión hacia arriba, si el compilador no puede deducir un tipo de destino concreto a partir del contexto, notifica un error.

En el siguiente código se muestra el uso de los operadores :> y :?>.En el código se muestra que el operador :?> es más conveniente cuando se sabe que la conversión se realizará correctamente, porque inicia InvalidCastException si se produce un error en la conversión.Si no existe certeza de que la conversión vaya a realizarse correctamente, es más adecuada una prueba de tipo que utilice una expresión match, mejor porque evita la sobrecarga de generar una excepción.

type Base1() =
    abstract member F : unit -> unit
    default u.F() =
     printfn "F Base1"

type Derived1() =
    inherit Base1()
    override u.F() =
      printfn "F Derived1"


let d1 : Derived1 = Derived1()

// Upcast to Base1.
let base1 = d1 :> Base1

// This might throw an exception, unless
// you are sure that base1 is really a Derived1 object, as
// is the case here.
let derived1 = base1 :?> Derived1

// If you cannot be sure that b1 is a Derived1 object,
// use a type test, as follows:
let downcastBase1 (b1 : Base1) =
   match b1 with
   | :? Derived1 as derived1 -> derived1.F()
   | _ -> ()

downcastBase1 base1

Dado que los operadores genéricos downcast y upcast se basan en la inferencia de tipos para determinar el argumento y el tipo de valor devuelto, en el código anterior se puede reemplazar

let base1 = d1 :> Base1

con

base1 = upcast d1

En el código anterior, el tipo de argumento y los tipos de valor devueltos son Derived1 y Base1, respectivamente.

Para obtener más información sobre las pruebas de tipo, vea Expresiones match (F#).

Vea también

Otros recursos

Referencia del lenguaje F#