Curso de Programación en C# [Comenzando con C#] Fecha: 10/Abr/2005 (04 de Abril de 2005)
|
Conversión de Tipos de Datos en C#
Las conversiones nos permiten que una expresión de un tipo sea tratada como una expresión de otro tipo, dichas conversiones pueden ser implícitas o explícitas, por ejemplo la conversión de un tipo int a long es implícita, sin embargo la conversión de un tipo long a un tipo int es explícita, esto debido a que un int puede ser expresado en formato long sin que haya perdida de precisión en la operación, sin embargo si intentamos convertir un numero long a int puede haber perdida de precisión y se necesita una conversión explícita, es como una forma de obligarnos a demostrar que estamos conscientes de que existe tal perdida de precisión y en verdad es muy útil. + Conversión Implícita - No requiere sentencias adicionales - Puede perder precisión, pero no magnitud + Conversión Explícita - La define el usuario utilizando la expresión (cast) - El operador "as" la convierte a un valor de tipo específico - Utilizar operadores "checked" y "uncheked" Ejemplo: int miNumero = 13; float miOtroNumero = miNumero; En este caso no es necesaria una conversión explícita debido a que un número int puede ser expresado sin ningún problema. float miNumero = 13.5; int miOtroNumero = (int) miNumero; En este caso si es necesaria una conversión explícita debido a que un número float no puede ser expresado en int sin que haya perdida de precisión, en este caso si ejecutaramos la siguiente instrucción: Console.WriteLine("Numero Float:{0} Numero Int:{1}",miNumero,miOtroNumero); se imprimiría en pantalla Numero Float: 13.5 Numero Int: 13 ahi podemos apreciar con claridad la perdida de precisión debido a que se trunca todo aquello que se haya después del punto, cabe hacer la aclaración que no se redondea, es decir no se eleva al entero más próximo, sino que se trunca.Operadores "checked" y "unchecked"
Los operadores checked y unchecked, se utilizan para controlar la verificación de ovewflow, de operaciones y conversiones aritméticas. + Expresión Verificada: - checked ( expression ) + Expresión no Verificada: - unchecked ( expression )Estructuras de Datos
+ Declaración: struct + nombreEstructura + { miembros }; + Uso: - Primero declaramos la estructura: struct coordenada { int x; int y; } - Después declaramos un objeto de ese tipo: coordenada miCoordenada; - Y accesamos a los elementos usando el operador . : miCoordenada.x = 1; miCoordenada.y = 2; Un tipo de estructura es un tipo de valor y puede crear constantes, campos, métodos, propiedades, índices, operadores, constructores de instancias, constructores estáticos y tipos anidados. Diferencias entre clases y estructuras + Estructura - Contiene datos simples - Tipo de Valor + Clase - Objeto enriquecido con referencias - Tipo de Referencia Ahi pocas diferencias entre estructuras y clases, pero son realmente significativas, las estructuras sirven para representar conjuntos de datos y pueden contener datos y funciones, sin embargo las estructuras son tipos de valor y no requieren espacio en la pila, ya que los datos están contenidos directamente en la estructura, mientras que una variable en una clase contiene una referencia a los datos, esto es lo que se conoce como objeto.Enúmerados
Una declaración enum declara un nuevo tipo enumerado e inicia con la palabra clave enum y define el nombre, la accesibilidad, el tipo y los miembros del enumerador. Cada tipo de enumerador tiene un tipo, dicho tipo debe poder representar todos los valores de numerador definidos en la enumeración. Un enumerado puede declararse de manera explícita un tipo como byte, sbyte, short, ushort, int, uint, long o ulong, cualquier enumerado que no indica de manera explícita su tipo es int. + Declaración: enum + nombreDelEnumerado + { valores } + Ejemplo: enum Color{ blanco,rojo,azul,verde }; + Uso: Color miColor; miColor = Color.blanco; miColor = (Color) 1;Arreglos
Los arreglos son una colección de elementos o de objetos todos del mismo tipo y que se encuentran indexados para poder acceder a ellos de una manera sencilla, son realmente faciles de usar, ahi diferentes tipos de arreglos Ahi dos formas de declarar arreglos en C# + Declaración con tipo y forma pero sin límites - int[] unidimensional; - int[,] bidimensional; - int [][] jagged; NOTA: Los arreglos del tipo jagged son arreglos de arreglos. + Declaración utilizando new con límites o inicializadores - unidimensional = new int[20]; - bidimendional = new int[20,20]; - jagged = new int[10][]; - jagged[0] = new int[][10];Métodos
Los métodos son miembros de las clases y pueden realizar una serie de acciones, o devolver un valor ya sea que tengan que calcularlo o no. Pueden recibir o no parametros y pueden devolver o no devolver parametros. + Declaración: tipoRetorno + NombreDelMétodo + [Parámetros] + { cuerpo } + Ejemplo: int Suma(int numero1, int numero 2) { return numero1 + numero2; } + Uso: [valor de retorno] miMétodo([Parametros]); + Ejemplo: resultado = Suma(numero1,numero2); Los métodos pueden recibir diversos valores desde el exterior, de hecho pueden recibir tantos valores como sea necesario, los valores que se le pasan a un método pueden ser por valor o por referencia, los valores que un método recibe por valor, los recibe como una copia del dato que puede modificar a su gusto sin que se vean afectadas las demás copias de dicho dato, en cambio los valores que un método recibe por referencia son las direcciones a donde se encuentra el dato, al cambiar el dato que ahí donde una de estas referencias apunta cambia el valor para todos aquellos que lo estan utilizando, un ejemplo muy sencillo de esto es, en el mundo real un paso de valor por referencia se da si tenemos apuntada la dirección de un amigo, dicha dirección es una referencia al lugar donde vive, es por eso que si vamos al lugar donde apunta la referencia nos encontraremos en la casa de nuestro amigo, una vez allí, si rompemos un vidrio cualquier persona que llegue a ese lugar encontrara la ventana rota, en cambio con los pasos de parámetro por valor se tiene una copia del objeto en si, es decir, en el ejemplo anterior en vez de haber tenido una dirección, habría tenido una casa exactamente igual a la de mi amigo, por lo que si hubiera roto un vidrio, solo mi casa se habría visto afectada. En C# si pasamos un valor a un método se pasa por valor a menos que se le indique lo contrario. Debemos recordar que no ahi limite al número de parámetros que puede recibir o devolver un método pero si no se va a recibir o a devolver ningún valor se puede usar la palabra void para indicarlo. En C# los métodos son sumamente flexibles, es por esto que podemos devolver múltiples valores y nos permite sobrecargarlos, las palabras claves ref y out son las que nos permiten que un método retorne más de un valor al método que lo invoco. La sobrecarga de métodos nos permite que un método se comporte de manera diferente en función al tipo de parametros que recibe y/o del número de argumentos que le acompañan. Ejemplos de sobrecarga de métodos: int i1=2,i2=3; float f1=2.14,f2=5.25; int suma( int n1, int n2 ) //Método 1 { return n1+n2; } float suma( float n1, float n2 ) //Método 2 { return n1+n2; } float suma( int n1, float n2 ) //Método 3 { return n1+n2; } resultado = suma(i1+i2); //Llamada 1 resultado = suma(f1+f2); //Llamada 2 resultado = suma(i1+f1); //Llamada 3 En este ejemplo en ninguno de los casos ahi perdida de precisión debido a que el método haciendo uso de la sobrecarga se adapta a los parametros que recibe y actúa en consecuencia a ello, es decir si el método suma recibe dos enteros como en la llamada 1 devuelve un número entero empleando para ello el método 1, si recibe dos flotantes devuelve un flotante utilizando para ello el método 2 y si recibe primero un flotante y luego un entero responde utilizando el método 3.Manejo de Excepciones
C# proporciona soporte integrado para el manejo de excepciones o de una forma más formal situaciones anómalas de funcionamiento, las cuales pueden ocurrir en cualquier momento durante la ejecución del programa y son manejadas por el código que se encuentra fuera del flujo normal de control. Todo esto gracias a las palabras clave try, throw, catch y finally. C# proporciona una solución estructurada tanto a nivel del sistema como de aplicación. A pesar de que es muy similar a C++ en cuanto al manejo de excepciones existen varias diferencias, entre ellas que cada excepción esta representada por una instancia de un tipo de clase derivado de System.Exception. en realidad es algo bastante simple: try { has esto... si i = 0 throw una excepción } catch { si fallo has esto... } finally { haya fallado o no, has esto... } Como se puede apreciar el manejo de excepciones es bastante sencillo y fácil de entender aunque no tengamos mucha experiencia programando, todo aquello que se puso entre las {} del try es un segmento de código en el que puede o no generarse un error en tiempo de ejecución(excepción), en caso de que haya habido un funcionamiento anómalo en el programa(excepción) la ejecución del código entra en el segmento de código catch y ejecuta el bloque de instrucciones que hemos definido para manejar ese error, finalmente el flujo del programa haya o no habido excepción entra en finally aqui podemos poner rutinas para marcar los objetos que ya no se utilizarán de manera que el recolector de basura pueda liberar la memoria que dichos objetos ocupaban, rutinas que guarden un log de la aplicación para llevar un control de ¿cuántas veces ha fallado?, ¿porqué fallo?, etc., todo bloque try puede tener uno o más catch para tratar cada una de las posibles excepciones, pero la flexibilidad de C# va más alla de eso, ya que nos permite lanzar nuestras propias excepciones, por ejemplo si un método no recibe un valor que debe recibir o recibe un valor que no puede procesar podemos lanzar nuestra propia excepción. Ejemplo: using System; public class ManejoExcepciones { public static void Main() { try //Le hacemos saber que puede ocurrir un error { string s=null; //Declaramos un string y lo dejamos vacio if (s == null) //Si el string esta vacio throw(new ExcepcionCadenaVacia()); //Lanzamos un error personalizado Console.WriteLine("Esto nunca se imprime"); //Si ahi error el código sale de la ejecución normal //es por eso que esta parte nunca se ejecuta } catch( ExcepcionCadenaVacia e ) //Atrapamos nuestro error { Console.WriteLine("La cadena esta vacia"); //Manejamos el error } finally { Console.WriteLine("Esto siempre se imprime"); //Esto siempre se ejecutará } } }NOTA IMPORTANTE: El código que se encuentra en los capitulos del curso no es siempre funcional. Para código funcional consulte la sección de ejercicios resueltos.