Conversiones de tipos en C

Anuncio
PROGRAMACION III – LABORATORIO III
Conversiones de tipos en C#
Dado que a C# se le asignan tipos estáticos en tiempo de compilación, después de declarar una variable, no se puede volver
a declarar ni tampoco utilizar para almacenar valores de otro tipo, a menos que dicho tipo pueda convertirse en el tipo de la
variable. Por ejemplo, no existe conversión de un entero a una cadena arbitraria cualquiera. Por lo tanto, después de
declarar i como entero, no puede asignarle la cadena "Hello", como se muestra en el código siguiente.
int i;
i = "Hello"; // Error: "Cannot implicitly convert type 'string' to 'int'"
Sin embargo, en ocasiones puede que sea necesario copiar un valor en un parámetro de método o variable de otro tipo. Por
ejemplo, puede que tenga una variable de tipo entero que deba pasar a un método cuyo parámetro es de tipo double.
Estos tipos de operaciones se denominan conversiones de tipos. En C#, puede realizar los siguientes tipos de conversiones:

Conversiones implícitas: no se requiere una sintaxis especial porque la conversión se realiza con seguridad de
tipos y no se perderán datos. Entre los ejemplos se incluyen las conversiones de tipos enteros de menor a mayor y
las conversiones de clases derivadas en clases base.

Conversiones explícitas (conversiones de tipos): las conversiones explícitas requieren un operador de
conversión. Las variables de origen y destino son compatibles, pero existe el riesgo de perder datos debido a que el
tipo de la variable de destino es más pequeño que (o es una clase base de) la variable de origen.

Conversiones definidas por el usuario: las conversiones definidas por el usuario se realizan a través de
métodos especiales que puede definir para habilitar las conversiones explícitas e implícitas entre tipos
personalizados que no tienen una relación de clase base-clase derivada. Para obtener más información, vea
Operadores de conversión (Guía de programación de C#).

Conversiones con clases auxiliares: para realizar conversiones entre tipos no compatibles, como los enteros y
los objetos System..::.DateTime, o bien cadenas hexadecimales y matrices de bytes, puede utilizar la clase
System..::.BitConverter, la clase System..::.Convert y los métodos Parse de los tipos numéricos integrados, como
Int32..::.Parse..
Conversiones implícitas
En los tipos numéricos integrados, puede realizarse una conversión implícita cuando el valor que se va a almacenar puede
ajustarse a la variable sin necesidad de truncamiento o redondeo. Por ejemplo, una variable de tipo longlong (Referencia de
C#) (entero de 8 bytes) puede almacenar cualquier valor que pueda almacenar a su vez un elemento intint (Referencia de
C#) (4 bytes en un equipo de 32 bits). En el ejemplo siguiente, el compilador convierte implícitamente el valor de la
derecha en un tipo long antes de asignarlo a bigNum.
// Implicit conversion. num long can
// hold any value an int can hold, and more!
int num = 2147483647;
long bigNum = num;
Tabla de conversiones numéricas implícitas
La tabla siguiente muestra las conversiones numéricas implícitas predefinidas. Las conversiones implícitas se pueden dar en
muchas ocasiones, incluidas la invocación a métodos y las instrucciones de asignación.
De
A
PROGRAMACION III – LABORATORIO III
sbyte
short, int, long, float, double o decimal
byte
short, ushort, int, uint, long, ulong, float, double o decimal
short
int, long, float, double o decimal
ushort
int, uint, long, ulong, float, double o decimal
int
long, float, double o decimal
uint
long, ulong, float, double o decimal
long
float, double o decimal
char
ushort, int, uint, long, ulong, float, double o decimal
float
double
ulong
float, double o decimal
Comentarios
Las conversiones de int, uint o long a float y de long a double pueden causar una pérdida de precisión, pero no

una pérdida de magnitud.

No existen conversiones implícitas al tipo char.

No hay ninguna conversión implícita entre los tipos de punto flotante y el tipo decimal.

Una expresión constante de tipo int se puede convertir a sbyte, byte, short, ushort, uint o ulong, siempre que
el valor de la expresión constante quede dentro del intervalo del tipo de destino.
Conversiones explícitas
Sin embargo, si no se puede realizar una conversión sin riesgo de perder información, el compilador requiere que se realice
una conversión explícita, denominada conversión de tipo. Una conversión de tipo es una manera de informar al compilador
de forma explícita de que pretende realizar la conversión y que está al tanto de que puede producirse una pérdida de datos.
Para realizar una conversión de tipo, especifique entre paréntesis el tipo al que se va a aplicar dicha conversión delante del
valor o la variable que se va a convertir. El programa no se compilará sin el operador de conversión de tipo.
class Test
{
static void Main()
{
double x = 1234.7;
int a;
// Cast double to int.
a = (int)x;
PROGRAMACION III – LABORATORIO III
System.Console.WriteLine(a);
}
}
// Output: 1234
Tabla de conversiones numéricas explícitas (Referencia de C#)
Las conversiones numéricas explícitas se utilizan para convertir cualquier tipo numérico a cualquier otro tipo numérico, para
el que no existe conversión implícita, mediante una expresión que utilice el operador de conversión explícita. La siguiente
tabla muestra estas conversiones.
De
Para
sbyte
byte, ushort, uint, ulong o char
byte
Sbyte o char
short
sbyte, byte, ushort, uint, ulong o char
ushort sbyte, byte, short o char
int
sbyte, byte, short, ushort, uint, ulongo char
uint
sbyte, byte, short, ushort, int o char
long
sbyte, byte, short, ushort, int, uint, ulong o char
ulong
sbyte, byte, short, ushort, int, uint, long o char
char
sbyte, byte o short
float
sbyte, byte, short, ushort, int, uint, long, ulong, charo decimal
double sbyte, byte, short, ushort, int, uint, long, ulong, char, floato decimal
decimal sbyte, byte, short, ushort, int, uint, long, ulong, char, float o double
Comentarios
 Las conversiones numéricas explícitas pueden producir pérdida de precisión o provocar excepciones.

Cuando se convierte un valor decimal en un tipo integral, este valor se redondea hacia cero al valor entero más
próximo. Si el valor entero resultante queda fuera del intervalo del tipo de destino, se produce una excepción
OverflowException.

Cuando se convierte un valor double o float en un tipo integral, el valor se trunca. Si el valor entero resultante
queda fuera del intervalo del valor de destino, el resultado depende del contexto de comprobación de
PROGRAMACION III – LABORATORIO III
desbordamiento. En un contexto comprobado, se produce una excepción OverflowException, mientras que en un
contexto no comprobado, el resultado es un valor no especificado del tipo de destino.

Cuando se convierte double en float, el valor double se redondea al valor float más próximo. Si el valor de tipo
double es demasiado pequeño o demasiado grande para ajustarse al tipo de destino, el resultado será cero o
infinito.

Cuando se convierte float o double en decimal, el valor de origen se convierte en una representación decimal y
se redondea al número más próximo después de la vigésimo octava posición decimal si es necesario. Según el
valor de origen, se puede producir uno de los siguientes resultados:

Si el valor de origen es demasiado pequeño para representarlo como decimal, el resultado se convierte
en cero.

Si el valor de origen es NaN (no es un número), infinito o demasiado grande para ser representado como
decimal, se produce una excepción OverflowException.

Cuando se convierte decimal en float o double, el valor decimal se redondea al valor double o float más
próximo.
LITERALES
ENTEROS
El tipo de un literal entero se determina como sigue:

Si el literal no tiene sufijo, su tipo es el primero de los tipos en los cuales se puede representar su valor: int, uint,
long, ulong.

Si el literal tiene el sufijo U o u, su tipo es el primero de los tipos en los cuales se puede representar su valor: uint,
ulong.

Si el literal tiene el sufijo L o l, su tipo es el primero de los tipos en los cuales se puede representar su valor: long,
ulong.

Si el literal tiene el sufijo UL, Ul, uL, ul, LU, Lu, lU o lu, es de tipo ulong.
REALES
Si no se especifica el sufijo de tipo real, el tipo del literal real es double. De lo contrario, el sufijo de tipo real determina el
tipo del literal real, como sigue:

Un literal real con el sufijo F o f es de tipo float. Por ejemplo, los literales 1f, 1.5f, 1e10f y 123.456F son de tipo
float.

Un literal real con el sufijo D o d es de tipo double. Por ejemplo, los literales 1d, 1.5d, 1e10d y 123.456D son de
tipo double.

Un literal real con el sufijo M o m es de tipo decimal. Por ejemplo, los literales 1m, 1.5m, 1e10m y 123.456M son
de tipo decimal. Este literal se convierte en un valor decimal tomando el valor exacto y, si es necesario,
redondeando al valor más cercano que se pueda representar mediante el redondeo de banca (Sección 4.1.7).
Cualquier escala que se detecte en el literal se conserva, salvo que el valor esté redondeado o sea cero (en este
caso, el signo y la escala son 0). Por lo tanto, el análisis del literal 2.900m forma un decimal con signo 0,
coeficiente 2900 y escala 3.
Si el literal especificado no puede representarse en el tipo indicado, se produce un error en tiempo de compilación.
El valor de un literal real de tipo float o double se determina mediante el uso del modo "redondeo al más cercano" de IEEE.
Tenga en cuenta que, en un literal real, siempre son necesarios dígitos decimales tras el punto decimal. Por ejemplo, 1.3F
es un literal real, pero no así 1.F.
Convert (Clase)
Convierte un tipo de datos base en otro tipo de datos base.
PROGRAMACION III – LABORATORIO III
Espacio de nombres: System
Comentarios
Esta clase devuelve un tipo cuyo valor es equivalente al valor de un tipo especificado. Los tipos base que se admiten son
Boolean, Char, SByte, Byte, Int16, Int32, Int64, UInt16, UInt32, UInt64, Single, Double, Decimal, DateTime y String.
Existe un método de conversión para convertir todos y cada uno de los tipos base en los demás tipos base. Sin embargo, la
llamada real a un método de conversión determinado puede generar uno de cuatro resultados, dependiendo del valor del
tipo base en tiempo de ejecución y el tipo base de destino. Estos cuatro resultados son:

Ninguna conversión. Esto sucede cuando se intenta convertir un tipo en sí mismo (por ejemplo, llamando a
Convert..::.ToInt32(Int32) con un argumento de tipo Int32). En este caso, el método devuelve una instancia del
tipo original.

Objeto InvalidCastException. Esto sucede cuando no se admite una conversión determinada. Se produce una
InvalidCastException para las conversiones siguientes:


Conversiones de Char a Boolean, Single, Double, Decimal o DateTime.

Conversiones de Boolean, Single, Double, Decimal o DateTime a Char.

Conversiones de DateTime en cualquier otro tipo excepto String.

Conversiones de cualquier otro tipo, excepto String en DateTime.
Una conversión correcta. Para las conversiones entre dos tipos base diferentes no mostradas en los resultados
anteriores, todas las conversiones de ampliación y todas las conversiones de restricción que no producen una
pérdida de datos serán correctas y el método devolverá un valor del tipo base concreto.

Objeto OverflowException. Esto sucede cuando una conversión de restricción produce una pérdida de datos. Por
ejemplo, al intentar convertir una instancia Int32 cuyo valor es 10000 en un tipo Byte se produce una
OverflowException porque 10000 está fuera del intervalo del tipo de datos Byte.
No se producirá una excepción si la conversión de un tipo numérico produce una pérdida de precisión, es decir, la pérdida
de algunos de los dígitos menos significativos. Sin embargo, la excepción se producirá si el resultado es mayor que lo que
puede representar el tipo de valor devuelto del método de conversión.
Por ejemplo, cuando un tipo Double se convierte en un tipo Single, se puede producir una pérdida de precisión pero no se
produce ninguna excepción. Sin embargo, si la magnitud del tipo Double es demasiado grande para que un tipo Single lo
represente, se produce una excepción de desbordamiento.
Descargar