0% encontró este documento útil (0 votos)
2 vistas46 páginas

Tema 3 Visual CSharp

La programación visual permite desarrollar aplicaciones con interfaces gráficas amigables, utilizando el paradigma de Programación Orientada a Eventos. C# es un lenguaje de programación de propósito general creado por Microsoft, que combina características de lenguajes como Visual Basic y Java. El documento también detalla cómo iniciar proyectos en Visual Studio, la estructura de aplicaciones de consola y gráficas, y conceptos básicos de programación en C#.

Cargado por

Felix
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
2 vistas46 páginas

Tema 3 Visual CSharp

La programación visual permite desarrollar aplicaciones con interfaces gráficas amigables, utilizando el paradigma de Programación Orientada a Eventos. C# es un lenguaje de programación de propósito general creado por Microsoft, que combina características de lenguajes como Visual Basic y Java. El documento también detalla cómo iniciar proyectos en Visual Studio, la estructura de aplicaciones de consola y gráficas, y conceptos básicos de programación en C#.

Cargado por

Felix
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

Tema 3.

Programación Visual

Visual C#

Sistemas Informáticos
(Grados en Ingenierías Industriales)

Conceptos básicos
 La programación visual ofrece los mecanismos necesarios
para diseñar y desarrollar aplicaciones con un entorno visual
amigable y fácil de utilizar para el usuario (friendly).

 La Programación Orientada a Eventos es un paradigma de


programación en el que la estructura y ejecución del programa
dependen de los sucesos (eventos) que ocurran en el sistema o
que ellos mismos provoquen.
 Algunos tipos de Eventos: click del ratón, pulsar tecla, cambio del foco,
modificar un cuadro de texto, seleccionar una fila de una tabla, seleccionar un
objeto de una lista, etc.

 El programador debe:
1. Diseñar la interfaz gráfica donde actúa el usuario.
2. Definir los eventos a los cuales el programa reaccionará, y las acciones a
efectuar al presentarse cada uno (manejador de eventos).

 Al ejecutarse un programa, se iniciará con un código inicial, y


luego el programa esperará a que ocurra un evento. 2

1
Características Principales de C#
 C# (leído en inglés “C Sharp” y en español “C
Almohadilla”) es el lenguaje de propósito general
diseñado por Microsoft para su plataforma .NET.
 Sus principales creadores son Scott Wiltamuth y
Anders Hejlsberg, éste último también conocido por
haber sido el diseñador del lenguaje Turbo Pascal y la
herramienta RAD Delphi (Rapid Application Development).
 La sintaxis y estructuración de C# es muy
similar a la C++, lo que facilita la migración de
códigos en este lenguaje a C# y su aprendizaje a
los desarrolladores habituados a ellos.
 En resumen, C# es un lenguaje de programación
que toma las mejores características de lenguajes
preexistentes como Visual Basic, Java, y C++ y
las combina en uno solo.
3

Empezar a Programar: Consola


 Una Aplicación de Consola se ejecuta en
una ventana de texto, sin interfaz gráfica:
 Visual Studio 2010:
 Menú Archivo  Nuevo  Proyecto.
 Escoger Tipo de Proyecto "Visual C#".
Las opciones exactas
pueden cambiar de  En la lista de Plantillas elegir "Aplicación de consola".
una versión a otra.
 Campo Nombre: Escribir el nombre del proyecto.
 Campo Ubicación: Indicar la carpeta.
 Visual C# Express Edition (versión gratuita):
 Primero escoger la ubicación de los archivos:
 Menú Herramientas  “Opciones”: Activar “Mostrar todas las
configuraciones”  Apartado "Proyectos y Soluciones": Cambiar la
“Ubicación de Proyectos”.
 Menú Archivo  Nuevo Proyecto.
 Escoger la plantilla de "Aplicación de consola".
 Campo Nombre: Escribir el nombre del proyecto. 4

2
Empezar a Programar
 Solución [Link]:
 Archivo de "Solución" de nivel
superior: Hay uno por aplicación.
 Contiene referencias a uno o más
archivos de proyecto (en este
caso sólo tiene un proyecto).
 Proyecto [Link]:
 Contienen códigos y objetos para el proyecto, escritos
siempre en el mismo lenguaje de programación.
 Tres partes:
1. Properties: [Link] contiene atributos del programa
(autor, fecha, título, compañía...).
2. References: Referencias al código compilado que puede
usarse. Bibliotecas/Ensambladores con código, como System.
3. [Link]: Archivo fuente C#, donde hay que escribir el
código. 5

Una aplicación básica using permite


incorporar clases no
Fichero [Link] definidas en nuestro
fichero. Por defecto se
using System; incluyen las más comunes
using [Link]; (en este ejemplo se pueden
quitar todas menos System).
using [Link];
using [Link];
using [Link]; Definición de una clase
por defecto para nuestro
namespace Ejemplo1 programa: Todas las
{ funciones deben
class Program pertenecer a alguna clase.
{
static void Main(string[] args)
{ [Link]("Hola mundo");
[Link](); // Pulsar enter
}
}
}
La clase [Link] Comentarios como en C++.
para entrada/salida por También: /* ... */
teclado/Pantalla.
6

3
Empezar a Programar
 Compilar:
 Menú Generar o Depurar  Generar Solución
 Errores: Se muestran en la ventana "Lista de
Errores".
 Para ver esa y otras ventanas: Menú Ver.
 Ejecutar:
 Menú Depurar  Iniciar depuración (F5):
 Ejecuta el código.
 Menú Depurar  Iniciar sin depurar (Ctrl-F5):
 Ejecuta y añade al final el texto "Presione una tecla para
continuar..."
 También se puede ejecutar paso a paso, para
depurar posibles errores.
7

Espacios de Nombres
 Es frecuente que varios objetos puedan tener el mismo nombre.
Para evitar confundirlos se crean los Espacios de Nombres.
 Ejemplo:
namespace Academia Esta clase se llama:
{ class Alumno
[Link]
{ ...
}
}

 Si otro módulo define otra clase Alumno, no se confundirá


con ésta, pues tendrá su propio espacio de nombres.
 Una “clase” es una definición de un tipo de objeto.
 Es recomendable definir todo en espacios de nombres y, por
eso, se crea uno por defecto con el nombre del proyecto
(namespace Ejemplo1 en el ejemplo anterior).
 Para evitar tener que poner siempre el nombre del espacio de
nombres, puede usar el comando: using <EN>;
 Evita tener que poner el espacio de nombres <EN>. 8

4
namespace y using
namespace Universidad
{
class Profesor // [Link]
{ ...
}
}
namespace Academia
{
class Profesor // [Link]
{ ...

}
}
 La sentencia using permite usar tipos sin escribir el nombre completo con los namespaces.
 Siempre se puede usar el nombre completo sin necesidad de utilizar “using”.
• Ejemplo: Declaramos 3 variables usando las dos clases anteriores:

using Universidad;

Profesor profe1; // Profesor de Universidad (nombre implícito)


[Link] profe2; // También de Universidad (nombre completo)

[Link] profe3; // Profesor de Academia

Una Aplicación Gráfica Simple


 Dos plantillas para aplicaciones gráficas:
 Windows Forms y WPF (Windows Presentation Foundation):
 WPF es una tecnología mejorada y preferible.
 WPF crea un formulario vacío (ventana en blanco)
llamado [Link] que se ve de 2 formas:
 Arriba: Forma gráfica del formulario o ventana.
 Abajo: Código XAML (eXtensible Application Markup
Language), que es un lenguaje para definir el diseño de un
formulario.
 Añadir controles usando el Cuadro de Herramientas:
 Está a la izquierda, o mostrarlo con el menú Ver.
 Cada control añade código XAML con sus propiedades
(ubicación, tamaño, nombre, tipo de letra...).
 Es más fácil cambiar las propiedades (de controles, del
formulario...) usando la "Ventana de Propiedades" (menú Ver).
10

5
Una Aplicación Gráfica Simple Los nombres por
defecto pueden
tener un número
al final.
 Agregar estos controles:
 Etiqueta (Label): C# usa el nombre por defecto label1.
 Cambiar algunas propiedades para probar, como el tamaño

de la letra: Propiedad FontSize.


 No confundir el nombre del control (Name) que se

muestra en la parte superior, con la propiedad Content


(contenido).
 Poner Content con: "Introduce tu nombre:".

 Caja de Texto (TextBox): Nombre por defecto textBox1.


 Cambiar nombre a "NombreUsuario" y vaciar Text.

 Botón (Buttom): Nombre por defecto button1.


 Nombre y contenido (propiedad Content) a "Ok".

 Propiedad Title del formulario a "Saludo" (clic en la


barra del título y cambiar su propiedad).
 Cambie tamaño de la ventana. 11

Una Aplicación Gráfica Simple


 Pruebe el programa:
 Menú Depurar (F5).
 El botón no hace nada.
 Cerrar la ventana (X superior).

 Visual Studio genera códigos automáticamente:


 Por ejemplo para mostrar el formulario inicial: Función
InitializeComponent();
 Se usa como constructor de la clase Window1.

 Fichero [Link]:
 Propiedad StartupUri: Indica qué ventana se empieza a

ejecutar (es como la función Main, aunque el código C#


está propiamente en el fichero [Link]).
 Nota: Podemos ver más controles, usando el botón derecho en el Cuadro de
Herramientas, opción “Elegir elementos”, pestaña “Componentes WPF”.
12

6
Una Aplicación Gráfica Simple
 Si hace doble clic sobre el botón del formulario:
 Se crea la función que se ejecutará cuando se use el botón
Ok (evento Click). Añadir este código:
private void Ok_Click(object sender, RoutedEventArgs e)
{
[Link]("Hola " + [Link]);
}

Muestra una ventana de Concatena "Hola "


mensajes con el mensaje con el texto que
que se indica. contenga el cuadro de
texto llamado
NombreUsuario
El nombre de la función, por
defecto, indica primero el
nombre del control, y luego Propiedad ToolTip: Texto que se muestra
el nombre del evento. cuando el ratón se pone encima de un
control. Útil para indicar para qué sirve.13

Palabras Reservadas
 No se pueden usar para otro propósito.
 Se escriben en azul en el editor de C#:
abstract, as, base, bool, break, byte,
case, catch, char, checked, class,
const, continue, decimal, default,
delegate, do, double, else, enum, event,
explicit, extern, false, finally, fixed,
float, for, foreach, goto, if, implicit,
in, int, interface, internal, lock, is,
long, namespace, new, null, object,
operator, out, override, params,
private, protected, public, readonly,
ref, return, sbyte, sealed, short,
sizeof, stackalloc, static, string,
struct, switch, this, throw, true, try,
typeof, uint, ulong, unchecked, unsafe,
ushort, using, virtual, void, while.
14

7
El método Main()

 La ejecución comienza en el método estático


Main().
 Solamente se puede tener un método con
una de las siguientes signaturas:

 static void Main()


 static int Main()
 static void Main(string[] args)
 static int Main(string[] args)

15

Sintaxis

 Identificadores:
 Son nombres para tipos, métodos, atributos,
variables, etc.
 Debe ser una palabra sin blancos.
 Caracteres Unicode.
 Debe empezar con una letra o subrayado (_).
 Distingue mayúsculas y minúsculas.
 No debe entrar en conflicto con palabras
reservadas.

16

8
Visión general

 Listas de sentencias  Condicionales


if
Bloques de sentencias


 switch
 Sentencias etiquetadas  Sentencias de bucle
 Tipos de Datos  while
 do
 Predefinidos y object  for
 Tipos Valor y Tipos Referencia  foreach
 Tipos definidos por el usuario  Manejo de excepciones
 try
 Declaraciones  catch
 Variables y Constantes (const)  throw
 Sentencias de salto
 Sentencias de expresiones  break
 using  return

• Las sentencias terminan con un punto y coma (;).


• Los bloques { ... } no necesitan punto y coma.
17

Variables y constantes
• Declaración similar a C++:
– No hay variables globales. • Con tipo float fallaría porque 3.14 es una
constante tipo double.
static void Main() • Habría que usar: const float pi = 3.14F;
• Lo mismo si es una variable (sin const).
{
const double pi = 3.14; // Constante
const int r = 2;

• Los enteros se convierten


int a, b = 2; // Variables int automáticamente a float,
float c = 3; // Variable float double, o decimal, porque
NO se pierde información.
a = 1;
[Link](a + b + c); // Escribe 6
[Link](pi * r * r); // Escribe 12.56
}

Aplicación de Consola: Ideal


para hacer pruebas simples. 18

9
Variables y constantes
 El ámbito de una variable o constante comienza en el punto
de declaración y finaliza al final de su bloque.
 Cada bloque o ámbito puede ser una función, una estructura
de control (for, while, if…).
 Dentro del ámbito de una variable o constante es un error
declarar otra variable o constante con el mismo nombre.

{
int x;
{
...
int x; // Error: ya existe x
...
}
...
}
19

Sentencias y expresiones

 Las sentencias deben hacer “algo”.


 Asignación, llamada a método, ++, --, new...

static void Main()


{
double a, b = 2, c = 3;
a = b + c;
a++;
b = [Link](b,2);
[Link](a + b + c); // 13
a == 2; // ERROR!
}

 La clase Math contiene funciones y constantes matemáticas


comunes (trigonométricas, logarítmicas, redondeo…):
 Ejemplos: Abs, Sin, Cos, Tan, Asin, Acos, Atan, Sinh, Cosh, Tanh, Exp,
Pow, Sqrt, Log, Log10, Round, Truncate, Floor, Ceiling…
20

10
Tipos Predefinidos o Primitivos
 Son “tipos valor”: No hay que reservar memoria
explícitamente, sino que basta con declarar una variable.
 Declarar variables (como en C): <tipo> <lista_variables>;

Entero sbyte, short, int, long


Natural (sin signo) byte, ushort, uint, ulong
Carácter char
Real float, double, decimal
Lógico bool
 Ejs.: int numero;
float Resistencia = 32.3F;
 Regla de asignación definitiva: C# genera un Error de
Compilación si se usa una variable sin asignarle un valor. 21

Tipos predefinidos o integrados


(bits)

Tipos
enteros

Tipos  Su tamaño depende del objeto.

Referencia  Su tamaño depende del texto.

• NOTA: Todos los tipos de datos primitivos en C# son objetos en el espacio de nombres System.
Para cada tipo, se proporciona un nombre corto o alias. Por ejemplo, int es el nombre corto
correspondiente a System.Int32, y double es la forma abreviada de [Link].
22

11
Tipos predefinidos: Tipos Reales

 float / double:
 Siguen la especificación IEEE 754.
 Soporta ± 0, ± Infinity, NaN.
 decimal:
 Usa 16 bytes: Esencialmente un valor de 96 bits
escalado por una potencia de 10.
 Comparado con double, tiene más precisión (29
dígitos significativos), pero un rango más
restringido (±1,0×10−28 a ±7,9×1028).
 No soporta ceros con signo, infinitos o NaN.
 Ejemplo:
decimal longitud = 6.69M;
23

Tipos predefinidos: bool

 Representa valores lógicos.


 Puede ser true o false.
 No se pueden utilizar 1 y 0 como
valores booleanos.
 No hay una conversión estándar entre
otros tipos y bool.

Tipo C# Tipo System Bytes


1
bool [Link]
(2 para arrays)

24

12
Tipos predefinidos: char

 Representa un carácter Unicode


 Literales:
 'A' // Carácter simple
 '\u0041' // Unicode
 '\x0041' // Unsigned short hexadecimal
 '\n' // Secuencia de escape

Tipo C# Tipo System Bytes


Char [Link] 2

25

Tipos predefinidos: char

 Caracteres de secuencias de escape (lista parcial):

Carácter Significado Valor


\' Comilla simple 0x0027
\" Comilla doble 0x0022
\\ Barra invertida 0x005C
\0 Null 0x0000
\n Nueva línea 0x000A
\r Retorno de carro 0x000D
\t Tab 0x0009

26

13
Tipos predefinidos: string
 Es una secuencia inmutable de caracteres Unicode.
 Se puede acceder a cada char usando el operador [ ].
 No se puede modificar: Para ello, usar arrays de char.
 Declaración y asignación: string s = "Soy un string";

 Es un Tipo Referencia: Al asignar una variable a


otra NO se copia el valor, sino la referencia.
using System;
Copiar esta clase en una aplicación de Consola.
class StringExample
{
public static int Main()
{
string s1 = "string 1";
string s2 = s1;
[Link]("s1 es " + s1);
[Link]("s2 es " + s2);
s1 = "Otro string";
[Link]("s1 es ahora " + s1); // Otro string
[Link]("s2 es ahora " + s2); // string 1
return 0;
}
} 27

El Sistema Unificado de Tipos


 Tipos valor:
 Directamente contienen datos: Ocupan un número fijo de bytes
según su tipo.
 No pueden ser null.
 La asignación copia los datos.
 Tipos referencia:
 Contienen referencias a objetos, cuyos tamaños son variables.
 Pueden ser null.
 La asignación copia la referencia al objeto (no el objeto).

int i1 = 123; i1 123


int i2 = i1
string s1 = "Hello world"; i2 123
string s2 = s1
s1 "Hello world"

s2
28

14
El Sistema Unificado de Tipos
 Conversiones implícitas:
 Ocurren automáticamente al asignar datos de distinto tipo .
 Se permiten si no hay pérdida de información (precisión).
 Conversiones explícitas:
Requieren un cast (molde, similar al lenguaje C).
Puede haber pérdida de información (precisión, signo...).
 Ambos tipos de conversiones pueden generar errores si no se
hacen bien y pueden ser definidas por el usuario.

int x = 123456;
long y = x; // implícita
short z = (short)x; // explícita: Riesgo de desbordamiento

double d = 1.2345678901234;
float f = (float)d; // explícita: Riesgo de perder decimales
long l = (long) d; // explícita: Riesgo de perder decimales

NOTA: Si en las explícitas se quita el molde generan error.

29

El Sistema Unificado de Tipos


 Todo es del tipo object (tipo referencia predefinido).
 Todos los tipos predefinidos, y los creados por el usuario heredan
de object:

...
 Implementa métodos de propósito general:
 public bool Equals(object obj)  Determina si el objeto
especificado es igual al objeto actual.
 Ej.: Para dos variables x e y del mismo tipo: if ([Link](y)) ...
 public string ToString()  Devuelve un string que representa al
objeto actual. Se emplea para crear una cadena de texto legible para el
usuario que describe el objeto. La implementación predeterminada devuelve
el nombre completo del tipo del objeto object.
 public Type GetType()  Obtiene el objeto Type del tipo exacto en
tiempo de ejecución de la instancia actual.
 Ej.: Si d es un double, también es un object, y esta sentencia escribe
“[Link]”: [Link] ([Link]());
30

15
Variables de tipo implícito: var
 C# tiene la palabra var para declarar variables cuyo
tipo tendrá que calcular C# a partir del valor de
inicialización:
 Ejemplos:
var valor = 99;
var frase = "Ya es tarde";

 La variable valor es de tipo int.


 La variable frase es de tipo string.
 Las variables declaradas de esta forma:
 Necesitan obligatoriamente ser inicializadas en su

declaración.
 No pueden cambiar de tipo durante la ejecución.

 Son útiles para ciertas aplicaciones, pero no deben usarse en

condiciones generales.
31

Tipos Definidos por el Usuario


 Son tipos en los que el usuario puede definir sus
características:
 Tamaño, número de datos, valores posibles en esos
datos...
 Algunos se explican más adelante.

Enumeraciones enum
Arrays int[], string[]
Interfaces interface
Tipos referencia class
Tipos valor struct
32

16
Clases y Objetos
 CLASE (class): Mecanismo para manipular
entidades en las aplicaciones (concepto similar
al TIPO de datos).
 Las aplicaciones necesitan manipular entidades:
 Cosas como clientes, motores, componentes... o algo
más abstracto como transacciones u operaciones.
 De cada entidad es importante conocer:
1. Estado: Es la Información que necesitamos, formada
por datos llamados Áreas, Campos o Atributos
(fields).
2. Métodos (Methods): Operaciones posibles sobre cada
objeto de esta clase (funciones o procedimientos).
 OBJETO (object, instance): Instancia de
una CLASE (concepto similar al de VARIABLE
de un TIPO de dato concreto).
 Los objetos de una clase comparten su
comportamiento. 33

Clases y Objetos
VEHÍCULO

ANIMAL

PUNTO_2D

FIGURA (1, 3)
(5, 2.5)
(2, 2)
(2, 1)
34

17
Estado y Métodos

1. Estado: Los valores de los atributos (campos, o


áreas) de un objeto (sus variables de instancia).
2. Métodos: Procedimientos (funciones) que definen el
comportamiento de una clase.
Pueden acceder a las variables de estado.

Pueden crear variables locales en cada método.


 Todas las variables y funciones deben pertenecer siempre a


una clase (por eso se crea siempre una por defecto).
 Ejemplo: Clase Punto_2D:
Punto_2D
x, y: double Estado (áreas, campos o atributos)
Inicializar()
Trasladar(x1, y1) Métodos (funciones o procedimientos)
Distancia(pto)
35

Definición de Funciones/Métodos
 La sintaxis de las funciones es similar a C/C++.
 Toda función (o método) debe estar en una clase.
 Deben devolver un valor (con return), o bien ser
de tipo void.
 Ej.: // Método que suma dos enteros:
// Muestra la suma y la devuelve
int Suma(int a, int b)
Para poner un { int resultado = a + b;
número en un
TextBox hay [Link] = [Link]();
que pasarlo a return resultado;
tipo string.
}
Objeto Método
 Llamada: Es similar a C.
 Para llamar a un método de un objeto se pone el nombre
del objeto y luego un punto: [Link]()
36

18
Definición de clases: Ámbito de variables

 Variables locales a un método: No pueden usarse en otros métodos.


 Variables de estado de una clase (Campos o Áreas):
 Pueden usarse en todos los métodos de (por defecto no pueden usarse fuera, son privadas).
 Se pueden usar para compartir información entre métodos.

class Clase1{ Variables de estado


int variableField = 0; // Area o Campo de Clase1
Métodos
void Metodo1()
{
int x = 1; // Variable LOCAL
variableField = 41; // Campo de esta clase
... // Se declara fuera, pero es de esta clase
}
void Metodo2()
{
variableField++;
x++: // ERROR: Variable no existe en este ámbito
...
}
} // Antes o después de esta clase se pueden definir otras, como la de Main...
37

Ejemplo: Circle, una clase simple


(con un programa de prueba para consola)

namespace ConsoleApplication1 Definición de una clase


{ class Circle // Clase para gestionar un círculo
{
public int radio; // Sólo tiene un campo: el radio (0 por defecto)
public double Area() // Método que calcula su área
{
return [Link] * radio * radio;  La palabra public indica que el
} radio y la función Area() se
} pueden usar fuera de la clase (por
ejemplo en la función Main().
class Program  Otra opción es private, lo cual se
{ explica más adelante.
static void Main(string[] args)
{
Circle c = new Circle(); // c es un objeto creado de clase Circle
Circle d = c; // c y d son el mismo objeto (son Tipos Ref.)
[Link]([Link]()); // Escribe 0 (se puede usar porque es public)
[Link] = 2; // Se puede cambiar el radio porque es public
[Link]([Link]()); // Escriben el area de radio 2
[Link]([Link]()); // Escriben lo mismo, porque son el mismo objeto
[Link] = 3;
[Link]([Link]()); // Escriben el area de radio 3
[Link]([Link]());
[Link]();  Sólo se ha creado un círculo, porque
} sólo se ha usado new una vez.
}  Hay dos variables Circle, que apuntan
} al mismo círculo. 38

19
Sentencias condicionales: if

 La sintaxis de la sentencia if es similar a C/C++.


 Requieren una expresión de tipo bool.

 Pueden anidarse indefinidamente.


 Si hay varias sentencias hay que usar un bloque,
entre llaves.
// Método para comparar dos enteros
int Test(int a, int b)
{
int res;
if (a > b) res = 1;
else if (a < b) res = -1;
else res = 0;
return res;
}
39

Sentencias condicionales: switch


 Puede utilizarse sobre cualquier tipo predefinido (incluyendo
string o enum).
 Los tipos definidos por el usuario pueden proporcionar conversiones
implícitas a estos tipos.
 Cada caso debe indicar explícitamente cómo finalizar con break
(aunque hay otras formas: return, throw, continue, goto <label>, y goto <case>).

int Test(string label)


{ int result; La instrucción break es obligatoria en
switch(label) todos los casos y en default, salvo
{ que un caso esté vacío.
case "Uno":
case "Otro 1": result = 1; break;
case "Dos": result = 2; break;
default: result = 0; break;
}
return result;
}
40

20
Ej: Mostrar Constantes de varios Tipos
 Crear una aplicación WPF con este formato:
 Objeto ListBox llamado EligeTipo : Inserte los ocho tipos de datos,
usando su propiedad Items (botón “...”).
 Botón “Agregar” escogiendo para las ocho opciones el tipo ListBoxItem.
 En la propiedad Content se deben escribir los ocho tipos de datos indicados.
 Programar el evento

SelectionChange del control


ListBox. Dos opciones:
1. Seleccionar el control ListBox, y en
su ventana de Propiedades, hacer
doble clic en dicho evento en la lista
de Eventos:
2. Hacer doble clic sobre el ListBox:
 NO hacer doble clic sobre un

item concreto.
 Ambas opciones abren la función que

se ejecutará cuando se cambie el


item seleccionado.
 Botón para salir debe tener este
código: [Link]();
41

Ej: Mostrar Constantes de varios Tipos

 Al cambiar de item, se muestra un valor de ejemplo del tipo:


private void EligeTipo_SelectionChange(object sender,
ListBoxItem TipoElegido=([Link] as ListBoxItem);

SelectionChangedEventArgs e)
{ switch ([Link])
{ case 0: [Link] = "42";
break;
case 1: [Link] = "42L"; // L es sufijo para long
break;
case 2: [Link] = "0.42F"; // F sufijo para float
Si en el switch queremos usar el string de cada opción:

break;
switch ([Link]())

case 3: [Link] = "0.42";


break;
case 4: [Link] = "0.42M"; // M sufijo decimal
break;
case 5: [Link] = "\"Cuarenta y dos\"";
break;
case 6: [Link] = "'x'";
{ case "int": …

break;
case 7: [Link] = "false";
. . .

break;
} Se ponen en el orden empleado, empezando en CERO:
}
int, long, float, double, decimal, string, char y bool. 42

21
Sufijos para constantes numéricas
 Las constantes numéricas (o literales) son de un tipo por
defecto, pero podemos cambiar ese tipo añadiendo un sufijo:
 Una constante entera sin sufijo será del primer tipo en el que se puede
representar su valor: int, uint, long, ulong.
 Las constantes reales se pueden escribir como enteros, como reales
con el punto, o en notación científica, y por defecto son double.
 Los sufijos pueden ir en mayúscula o minúscula, pero se recomienda
usar siempre mayúscula.

Tipo de Dato Sufijo Ejemplos


uint,ulong U 42U
long,ulong L 42L
ulong UL / LU 42UL
float F 42F 4.2e1F
double D 42D -3.45e-3
decimal M 42M -3.45e-3M

43

Error Típico de Compilación (CS1061)


 Mensaje de error típico:
 'tipo' no contiene una definición de 'miembro' ni se encontró ningún método de
extensión 'nombre' que acepte un primer argumento de tipo 'tipo' (¿falta una
directiva using o una referencia de ensamblado?).
 Causa: Este error se produce cuando se intenta llamar a un método o tener
acceso a un miembro de clase, que no existe.
 Soluciones:
 Revisar que está definido el método que se está usando: Puede que tenga otro
nombre, o que pertenezca a otra clase…
 Suele ocurrir que un control tiene asociada esa función a un evento, y esa función
no exista (porque se haya borrado o cambiado de nombre).
 Soluciones: Crear la función, o bien dejar de asociar esa función a ese evento en la
ventana Eventos de ese control:
 Ejemplo:
 Si hacemos doble click sobre un control TextBox, se crea la función TextBox1_TextChanged(),
que se asocia al evento TextChanged, el cual ocurre cuando “cambia texto en el control”.
 Si esa función no la queremos, podemos borrarla pero ya está asociada a ese evento, por lo que
dará un error de compilación, con el mensaje: 'Aplicación' no contiene una definición de
'TextBox1_TextChanged' ni se encontró ningún método de extensión…
 Para eliminar esa asociación función-evento:
 Buscar el evento en la lista de eventos del control, y borrar dicha función.
También se puede buscar el evento en el código XAML y quitarlo.
44

22
Operadores de C#
 C# proporciona operadores, cuyo significado está
definido para los tipos predefinidos.
 Algunos operadores pueden ser sobrecargados.
 Ej: La suma + sirve para varios tipos.
 Asociatividad:
 Los operadores de asignación y el condicional ternario son
asociativos hacia la derecha: Las operaciones son realizadas de
derecha a izquierda.
 Ej.: x = y = z se evalúa como x = (y = z)
 Los demás operadores binarios son asociativos hacia la
izquierda: Operaciones se ejecutan de izquierda a derecha.
 Ej.: x + y + z se evalúa como (x + y) + z
 Utilizar paréntesis para controlar el orden.

45

Operadores: Por Precedencia


 Las siguientes tablas resumen los operadores de C#
por categorías.
 Las categorías están en orden de precedencia decreciente.
 Los operadores de cada categoría tienen la misma
precedencia.
Categoría Operadores
Valor positivo de: +
Valor negativo de: –
Not: !
Unarios Negación (bits): ~ (complemento a 1)
Pre(post)-incremento: ++x (x++)
Pre(post)-decremento: – –x (x– –)
Molde o Casting: (Tipo) x
Multiplicación: *
Multiplicativos División: /
Resto: % (de todo tipo: 7.0 % 2.4  2.2)
46

23
Operadores: Por Precedencia
Categoría Operadores
Sumar: +
Aditivos
Restar: –
Desplazamiento Shift bits left: <<
(bits) Shift bits right: >>
Menor que: <
Mayor que: >
Menor que o igual a: <=
Lógicos
Mayor que o igual a: >=
Igualdad/compatibilidad de tipos: is
Conversión de tipos: as

int a = 2;
[Link]("a<<1 es {0} y a<<2 es {1}", a<<1, a<<2); // 4 y 8
[Link]("a>>1 es {0} y a>>2 es {1}", a>>1, a>>2); // 1 y 0

47

Operadores: Por Precedencia


Categoría Operadores
Igual: ==
Igualdad
No igual: !=
AND (bits) &
XOR (bits) ^
OR (bits) |
AND lógico condic. &&
OR lógico condic. ||
Condicional
?:
ternario
Asignación =, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |=

int a = 2, b = 3;
[Link]("a&b es {0} y a|b es {1}", a&b, a|b); // 2 y 3
[Link]("a^b es {0} y ~a es {1}", a ^ b, ~a); // 1 y -3

48

24
Operadores: Observaciones
 Tipo de una operación: depende del tipo de sus
operandos:
 Expresión double: 5.0 / 2.0  Resultado: 2.5
 Expresión int: 5 / 2  Resultado: 2
 Expresión double (usa int-double): 5 / 2.0  2.5
 Esta mezcla de tipos funciona pero no se recomienda.

 Dividir por cero:


 Los tipos enteros no permiten dividir por cero: El resultado es
infinito y genera un error.
 Los tipos double y float aceptan ± Infinity.
 Constantes: [Link] y [Link].
 La división 0.0/0.0 es una paradoja y genera el valor NaN (Not A
Number), que se usa con la constante [Link].
 Los valores NaN e Infinity se propagan por las expresiones:
 Ejemplos: 5+NaN  NaN 5+Infinity  Infinity
NaN*0  NaN 49

Ej: Volumen de un Tonel (aplicación WPF)


 Escriba un programa que lea las medidas de un tonel
y nos devuelva su volumen: Volumen =  L a2
 L es la altura del tonel.
 a = d/2 + 2/3(D/2 - d/2)
 d es el diámetro del tonel en sus extremos.
 D es el diámetro del tonel en el centro: D>d
 Nota: Si las medidas están en centímetros el resultado se obtiene en centímetros cúbicos.

 Ventana Principal: Cambiar estas


propiedades:
 Title, con un nombre.

 ResizeMode a “CanMinimize”,
para que permita minimizar la
aplicación, pero no cambiar su
tamaño.
 Llamar a los Cuadros de Texto
respectivamente: L, d, D, y Volumen.
 En Volumen, marcar la propiedad
IsReadOnly, para que no pueda
escribirse en él.
 Mostrar ventanas de error si hay
valores negativos, o si d>D.
50

25
Ej: Volumen de un Tonel (aplicación WPF)

 Evento Click del botón llamado CalcularVolumen:

private void CalcularVolumen_Click(object sender, RoutedEventArgs e)


{
double LL = [Link]([Link]), //Conversión de cadena a double
dd = [Link]([Link]),
DD = [Link]([Link]);
if (dd>DD)
[Link]("Diámetro menor debe ser menor que el mayor.");
else if (dd < 0 || DD < 0 || LL < 0)
[Link]("Poner valores positivos siempre.");
else
{ double a = dd/2 + 2/3.0 * (DD/2 - dd/2);
double V = [Link] * LL * a * a;
[Link] = [Link](); // Conversión de double a cadena
}
} Cada clase tiene el método ToString para convertir el
objeto a una cadena.
En este caso, V como string se asigna a un TextBox.

Math es una clase con utilidades matemáticas:


• Métodos (funciones) : Abs, Sqrt, Sin, Cos, Tan, Exp, Pow, Log, Log10...
• Constantes (áreas) : PI y E.
51

Ej: Volumen de un Tonel (aplicación WPF)


 Añadir un ComboBox llamado Unidades, para escoger la unidad de medida.
 Añadir 3 unidades de medida posibles: “m.”, “cm.”, y “mm.”.
 Usar la propiedad Items: Botón “Agregar” escogiendo ComboBoxItem para las tres unidades, y
poner el texto de la unidad en su propiedad Content.
 Introducirlas en ese orden, o cambiar su orden usando las flechas.
 Para el item “m.” marcar su propiedad IsSelected, para que aparezca seleccionado por defecto.
 Añadir un Label llamado Unidades3, tras el resultado para mostrar la unidad de
medida del volumen resultante, que debe cambiar AL PULSAR EL BOTÓN:
 Al final del evento Click: . . .
[Link] = [Link](); // . . .
switch ([Link])
{
case 0: [Link] = "m^3"; break;
case 1: [Link] = "cm^3"; break;
case 2: [Link] = "mm^3"; break;
}

 Modificaciones adicionales:
 Mostrar el resultado también en litros, siempre.
 Redondear a 5 decimales: V = [Link](V, 5);
 Poner el texto “Pulsa botón” en los dos volúmenes, cuando
se cambie alguno de los 3 datos de entrada.
 Poder poner cada dato de entrada en una unidad de medida, y
el resultado mostrarlo en todas.
52

26
Ej: Volumen de un Tonel (aplicación WPF)
 Mostrar el resultado también en litros (o decímetros cúbicos, dm3):
. . .
switch ([Link])
{
case 0: [Link] = "m^3";
V = V * 1000; // Conversión a litros: 1 m^3 = 1000 l.
break;
case 1: [Link] = "cm^3";
V = V * 1e-3; // Conversión a litros: 1 cm^3 = 0.001 l.
break;
case 2: [Link] = "mm^3";
V = V * 1e-6; // Conversión a litros: 1 mm^3 = 0.000001 l.
break;
}
Vol_litros.Text = [Link]();

 Borrar resultados cuando se cambia alguno de los 3 valores de entrada: Programar


los 3 eventos TextChanged de los 3 cuadros de texto de entrada.
private void L_TextChanged (object sender, TextChangedEventArgs e)
{
Vol_litros.Text = [Link] = "Pulsa botón.";
}

 NOTA: Si se genera al compilar el error “el codigo de usuario no controló nullreferenceexception”, se


debe definir (dentro del Grid del código XAML) los dos TextBox que se usan en las 3 funciones (Volumen y
Vol_litros), ANTES que los 3 TextBox que los usan en su evento (cuadros de texto L, d y D).
53

Ej: Calculadora Sencilla (aplicación WPF)


 Controles y nombres:
 4 TextBox: Llamados opIzdo,
opDcho, expresion y resultado.
 5 RadioButton: Propiedades:
 Name: Las operaciones.
► Puede poner valores iniciales en los operandos

► Si un RadioButton está marcado al inicio su

 Content: Como se muestra.


IsChecked: False (ninguno
► No se controlan errores de conversión.

debe estar marcado al inicio).


evento Checked se lanza al inicio.

 Doble clic sobre un RadioButton despliega la función del evento


Checked, que se ejecuta cuando es seleccionada esa opción:
private void Suma_Checked(object sender, RoutedEventArgs e)
(propiedad Text).

{ double izdo = [Link]([Link]), //Conversión


dcho = [Link]([Link]),
result;
[Link] = [Link] + " + " + [Link];
result = izdo + dcho;
[Link] = [Link](); //Convertir a cadena
NOTAS:

} Recuerde:
• <tipo>.Parse(cad) convierte la cadena cad a un número de ese tipo.
• <variable>.ToString() convierte esa variable a cadena (no tiene argumento). 54

27
Esquema de la Calculadora Sencilla
 Esquema del Documento:
 Se accede con el botón derecho sobre el
formulario o en el menú Ver (otras ventanas).
 Muestra todas las herramientas de una
ventana.
 Por defecto una ventana tiene un elemento
llamado Grid.
 Grid es un "panel" que gestiona cómo posicionar los
controles, principalmente cuando la ventana cambia
de tamaño.
 Grid es flexible pero complejo: Por defecto tiene sólo
una celda en la que poner los controles, pero pueden
definirse múltiples filas y columnas.
 Estas propiedades de los demás controles están
referidas al panel en el que se encuentran:
 HorizontalAlignment: Valores Right/Left/Center/Stretch.
 VerticalAlignment: Valores Top/Down/Center/Stretch.
 Stretch estira el elemento para rellenar todo el espacio
menos los márgenes establecidos.
 Margin: Son 4 valores (izda,arriba,dcha,abajo), que miden
las distancias según la alineación.
 Existen otros controles panel:
 StackPanel: Sitúa los controles verticalmente.
 WrapPanel: Los sitúa en filas de izda. a dcha., cambiando
de fila cuando una fila se llena. 55

Ej: Calculadora Sencilla


 Añadir un Botón "Intercambiar" entre los dos operandos:
 El botón intercambiará los dos operandos.
 Si hay algún RadioButton marcado, debería actualizar los
resultados (especialmente en las operaciones que no cumplen la propiedad conmutativa).

private void Intercambiar_Click(object sender, RoutedEventArgs e )


{ string aux = [Link]; // Intercambiar valores
[Link] = [Link];
[Link] = aux;
if ((bool)[Link]) // La Suma y la Multiplicación
Resta_Checked(sender, e); // no hay que rehacerlas
else if ((bool)[Link])
Dividir_Checked(sender, e);
else if((bool)[Link]) Puede incluir también la Suma y la
Multiplicación para que haga el
Resto_Checked(sender, e); cambio (aunque el resultado no
} cambia, cambiará la expresión.

 El molde (bool) del if es necesario porque la propiedad IsChecked es de un tipo bool


nullable, es decir, que puede contener el valor Null, el cual no lo admite if.
56

28
Sentencias de bucle: while y do-while

 Sintaxis similar a C/C++ y Java.


 Requiere una expresión booleana.
 Diferencias:
 while se ejecuta cero o más veces.
 do-while se ejecuta una o más veces:
 Requiere un punto y coma final.
 Ejemplos:
int i = 0; int i = 0;
while (i < 5) do
{ {
... ...
i++; i++;
} }
while (i < 5);
57

Sentencias de bucle: for


 Sintaxis similar a C/C++, con 3 expresiones (opcionales):
Inicialización, Condición (tipo while) y Actualización.
 Si se declaran variables en la Inicialización no se pueden usar
fuera del bucle:
 Su ámbito es el bucle y, por tanto, otros bucles pueden volver a
declarar otra variable con el mismo nombre.
 Ejemplo: Inicialización Condición Actualización

for (int i=0; i < 5; i++)  Inicialización: Se ejecuta


sólo una vez, al principio.
{  Condición: Se ejecuta al
... principio de cada iteración.
 Actualización: Se ejecuta
} al final de cada iteración.

 Notas:
 La Inicialización y la Actualización pueden ser múltiples separando cada
una por coma. Si ambas se dejan vacías es como poner un while.
 Existe el bucle foreach que es especial para recorrer arrays.
58

29
Ej: Calcular divisores (aplicación WPF)

 Controles y nombres:
 Dos TextBox llamados numero
y divisores.
 En el segundo cambiar estas
propiedades: Auto en
VerticalScrollBarVisibility y
HorizontalScrollBarVisibility, y
marcar IsReadOnly.
 Una etiqueta y dos botones.

private void Calcular_Click(object sender, RoutedEventArgs e )


{ int num = [Link]([Link]);
int divisor = num - 1;
[Link] = [Link];
while (divisor > 1)
{ if (num % divisor == 0)
[Link] += '\n' + [Link]();
divisor--;
}
[Link] += '\n' + "1";
}
59

Ej: Calcular divisores (aplicación WPF)


 Mostrar etiqueta "¡ES PRIMO!" si hay sólo dos divisores:
 La propiedad Visibility de la etiqueta debe estar inicialmente a Hidden
y ponerse a Visible cuando haya sólo 2 divisores (hay que contarlos):

if (num_divisores == 2)
[Link] = [Link];

 Cuando se cambie el número, se debe volver a


poner a Hidden y también se deben borrar sus
divisores (para evitar malentendidos):
 Seleccionar el cuadro de texto “numero” y en la caja
de propiedades pulsar sobre el botón superior de
Eventos para mostrar todos los eventos de ese objeto
(ahí se puede asociar cada evento a una función).
 Doble click sobre el evento TextChanged abre la
función a ejecutar cuando se produzca ese evento.

private void numero_TextChanged(object sender, TextChangedEventArgs e)


{ [Link] = [Link]; // Ocultar si es o no primo
[Link] = ""; // Borrar divisores anteriores
}
60

30
Sobrecargar Métodos
 Se pueden declarar dos métodos con el mismo nombre siempre
que tengan distinto número y/o tipo de argumentos.
 El valor de retorno se ignora.
 Según los argumentos de la llamada, el compilador sabrá qué
método ejecutar.
 Es útil cuando necesita realizar la misma operación en distintos
tipos de datos.
 Muchos métodos estándar de C# están sobrecargados.
 Ejemplos:

void Print(int i);


void Print(string s);
void Print(char c);
void Print(float f);
int Print(float f); // ERROR: cabecera duplicada

61

Utilidades del Editor de Visual Studio


 Generar Método automáticamente: Si escribimos la llamada a una
función que aún no ha sido programada, podemos situar el cursor sobre dicha llamada
y con el botón derecho usar la opción "Generar código auxiliar del método": Se
generará la cabecera de la función automáticamente, con una sentencia dentro:
throw new NotImplementedException();
 Refactorizar código: Si se marca un fragmento de programa y se usa la
opción "Refactorizar  Extraer método", el sistema genera una función que
sustituye a ese código: Revisarla bien.
 Cambiar de nombre un símbolo: Sobre dicho símbolo usar la opción
"Refactorizar  Cambiar nombre". Indicar nuevo nombre y validar los cambios.
 DEPURADOR: Ejecutar paso a paso, visualizar/cambiar variables...
 Situar el cursor en la línea en la que se quiere parar la ejecución y usar la
opción del botón derecho: "Ejecutar hasta el cursor" (Ctrl-F10).
 Ver el valor de una variable: Poner el cursor sobre su nombre.
 Menú Depurar: Paso a paso por instrucciones (F11) o por
procedimientos (F10), detener depuración (May-F5)…
 Ventana Variables Locales: DepurarVentanasVars. Locales.
 Ventana Inmediato: Evaluar expresiones, ejecutar instrucciones...
62

31
Manejo de excepciones
 Las excepciones son el mecanismo de C# para manejar
condiciones de error graves e inesperadas cuando el programa
se está ejecutando.
 El error producido impide al programa continuar, por lo que hay
que hacer algo específico: Informar al usuario para que aporte
información, usar valores distintos…
 Una excepción es cualquier error o comportamiento inesperado
encontrado en la ejecución de un programa que impide continuar.
 Pueden ser o no culpa del usuario de la aplicación.
 No pueden ser ignoradas.
 No tienen que ser manejadas en el punto en el que ocurren.
 Se proporcionan excepciones estándares.
 El usuario puede definir sus propios tipos de excepciones.
 Observaciones:
 Son superiores a los valores de retorno.
 Pueden ser usadas incluso en situaciones donde no se podrían retornar valores (Ej:
accediendo a una propiedad).
63

Manejo de excepciones
 Sentencias: try... catch... finally...
 Bloque try:
 Contiene código que podría lanzar o generar excepciones.
 Si no hay excepciones se ejecuta completamente.
 Si se produce una excepción, la ejecución salta fuera del
bloque try y va al manejador de la excepción (bloque catch
específico).
 Bloque catch:
 Un bloque catch maneja una excepción (o varias).
 Pueden existir múltiples bloques catch para manejar
diferentes clases de excepciones de forma separada.
 Bloque finally:
 Contienen código que se ejecutará siempre al final.
 Es opcional.

64

32
Manejo de excepciones
try
{
// Código para ejecución normal
}
catch (<Exception> <VariableEx>)
{
// Manejo de errores (puede haber varios bloques catch)

}
finally
{
// Limpieza o liberación de recursos
}

 <Exception> Es el tipo de excepción que se manejará en ese bloque.


 <VariableEx> Es la variable (opcional) que contendrá los detalles de
la excepción.
 Sus propiedades dependen del tipo de excepción pero hay muchas que son
comunes (<VariableEx>.Message es el mensaje de error).
65

Excepciones: Ejemplo simple


Izdo y Dcho son cuadros de texto donde se supone que habrá enteros:
 Si hay caracteres no válidos, Parse lanza un FormatException.
 Con números muy grandes, Parse lanza un OverflowException.

try
{ int OpIzdo = [Link]([Link]);
int OpDcho = [Link]([Link]);
int respuesta = Calculos(OpIzdo, OpDcho);
[Link] = [Link]();
}
catch (FormatException fEx)
{ [Link]("ERROR: Introduce enteros. "
+ [Link]);
}
catch (OverflowException oEx)
{ [Link]("ERROR: Enteros muy grandes. "
+ [Link]);
}
66

33
Excepciones: Buscando el manejador

 Si no hay manejador (catch) para una excepción


concreta, cuando se produce esa excepción se sale de la
función y busca un manejador en la función superior que
llamó a esa... y así sucesivamente.
 Si encuentra un manejador para esa excepción: Se ejecuta
y luego continúa con los comandos que haya tras ese catch.
 La ejecución no vuelve al método que provocó la excepción.
 Si NO se encuentra un manejador para esa excepción: El
programa termina con una excepción no manipulada.
 Dentro del entorno de programación podremos ver el tipo de
excepción generada y buscar su causa.
 Una excepción es, por tanto, un error grave que
impide al programa continuar su curso normal:
 Se debe gestionar ese error para evitar que la aplicación termine
anormalmente.
67

Excepciones
 Se organizan en familias,
formando una jerarquía.
 Ej.: SystemException
engloba a FormatException y
a OverflowException.
 Exception: Familia superior.
 Capturando esta se atraparán todas
las excepciones posibles.

catch (Exception ex)


{ // Manejador General
...
}
 Se ejecuta SÓLO el primer
manejador que se encuentre:
 El manejador general de
Exception debe ir siempre al
final.
 Poner los manejadores específicos
antes que los generales. 68

34
Excepciones: Ejemplo en el ejercicio del Tonel
private void CalcularVolumen_Click(object sender, RoutedEventArgs e)
{ try
{ double LL = [Link]([Link]), //Conversión a double
dd = [Link]([Link]),
DD = [Link]([Link]);
if (dd > DD)
[Link]("El diámetro menor debe ser menor que el mayor.");
else if (dd < 0 || DD < 0 || LL < 0)
[Link]("Poner valores positivos siempre.");
else { double a = dd / 2 + 2 / 3.0 * (DD / 2 - dd / 2);
. . . // Falta código aquí...
}
}
Captura la excepción, si algún Parse genera un error de formato.
NOTA: Para saber qué Parse generó el error podemos usar una variable
catch (FormatException) int X=1; declarada antes de try y que incrementamos tras cada Parse, y
{ en el módulo catch ponemos un if (X==1) ... else if (X==2) ...

[Link]("ERROR: Introduce números.");


} Captura la excepción cuando se introduce un número muy grande:
catch (OverflowException) Probar, por ejemplo, 1e309 (fuera del rango de double).
{ Nota: Con números muy grandes el resultado podría ser “Infinito”.
[Link]("ERROR: Número/s excesivamente grande/s.");
}
catch (Exception exc) // Manejador general Captura cualquier otra excepción (por si
{ acaso se nos olvida controlar algún otro
posible error).
[Link]("ERROR: " + [Link]);
Se incluye la variable exc porque se
}
usa para mostrar el mensaje del error:
} [Link] 69

Excepciones: Bloque finally

 Una excepción altera el flujo de ejecución del programa:


 Pueden existir instrucciones que no se ejecuten.
 Si las instrucciones que no se ejecutan son importantes,
pueden generarse problemas.
 Si hay algún recurso asignado hay que liberarlo para que
pueda usarlo otro proceso y para liberar memoria:
 Ej.: Archivos usados, o conexiones a Bases de Datos (deben
cerrarse al final, cuando ya no son útiles).
 El bloque finally se ejecuta SIEMPRE:
 Se ejecuta tanto si se lanza una excepción como si no.
 Si la excepción tiene manejador local, primero se ejecuta ese
manejador.
 En otro caso, primero se ejecuta el bloque finally y luego se
buscará el manejador en la lista de métodos lanzados
anteriormente.
70

35
Excepciones: Lanzar con throw
 Sentencia throw: Lanza una excepción explícitamente.
 Cuando ocurre algún hecho que impida la ejecución normal del
programa.
 Una excepción es una instancia de
[Link] o de una clase derivada:
 Contiene información sobre la excepción. Propiedades:
 Message: Texto que describe la condición de error
 StackTrace: Secuencia de llamadas a métodos que provocaron la
excepción.
 Hay excepciones predefinidas para la mayoría de los errores
comunes y si no, se pueden crear nuevas.
 Ej.: Si un argumento se sale de rango, existe la excepción
ArgumentOutOfRangeException.
 Crear nuevos tipos de excepciones permite personalizar nuestros
tipos de errores y un mejor control de ellos.
 Se puede relanzar una excepción, o capturar una
excepción y lanzar otra diferente.
71

Manejo de Excepciones: Ejemplo


Aplicación de Consola de Ejemplo.

try
{ [Link]("Bloque try");
throw new Exception("Mensaje de error.");
[Link]("Esto no se ejecuta.");
}
catch (ArgumentNullException e) // No se produce
{ [Link]("Argumento null"); Un manejador general
captura las excepciones
} específicas, pero no al revés.
catch (Exception e)
{ [Link]("catch: " + [Link]);
}
finally
{ [Link]("Bloque finally");
}
Bloque try
 Escribe: catch: Mensaje de error.
Bloque finally
72

36
Herencia
FiguraCerrada

• Posibilidad de reutilizar código

• Algo más que:


Polígono Elipse
• incluir ficheros, o
• importar módulos

• Distintos tipos de herencia: Pentágono Cuadrilátero Círculo


• simple / múltiple
• estricta
• selectiva
• de implementación / de Cuadrado Rombo
interfaz

73

Polimorfismo y Vinculación Dinámica


 Un lenguaje tiene capacidad polimórfica sobre los datos cuando
una variable declarada de un tipo (o clase) –tipo estático–
determinado puede hacer referencia en tiempo de ejecución a
valores (objetos) de tipo (clase) distinto –tipo dinámico–.
 La capacidad polimórfica de un lenguaje no suele ser ilimitada, y en
los LOO está habitualmente restringida por la relación de herencia:
 El tipo dinámico debe ser descendiente del tipo estático.
 Ejemplo:

Se declara un array
de tipo
FiguraCerrada.
En tiempo de
ejecución los
elementos son
Rombo, Círculo,
etc.
74

37
Polimorfismo y Vinculación Dinámica
• La vinculación dinámica resulta el complemento
indispensable del polimorfismo sobre los datos, y
consiste en que:
– La invocación del método que ha de resolver un mensaje se
retrasa al tiempo de ejecución, y se hace depender del tipo
dinámico del objeto receptor.

Polígono :Polígono
perímetro{^...}
obj : Cuadrado

Cuadrado :Cuadrado
perímetro{^4*lado}

75

Definir una Clase simple: class


 Se usa la palabra clave class y, entre llaves se
definen los campos y los procedimientos:
 Ejemplo:
class Circle
Se declara antes o después { public int radio;
de la clase principal class
Program. public double Area()
{ return [Link] * radio * radio;
Math es una clase con }
procedimientos y áreas
matemáticas: Sqrt...
}

 Crear una instancia (objeto) de una clase:


 Al declarar una instancia, dicha instancia no tiene ningún valor,
ni espacio asignado: Vale null (es un tipo referencia).
 Para contener un objeto, reservar su memoria con new:

Circle c = new Circle(); // c es un objeto


Circle d = c; // Ambos son el mismo objeto,
// no dos objetos iguales.
76

38
Clases: Accesibilidad y Uso
 Accesibilidad: Controla desde dónde se puede
acceder a cada atributo y procedimiento de una clase,
individualmente:
 Privados (private): Atributos y procedimientos que sólo se
pueden acceder desde otros procedimientos de la misma clase
(por defecto).
 Públicos (public): Son accesibles desde el interior y exterior
de la clase.
 En el ejemplo anterior, si Circle tuviera todos sus atributos y
procedimientos privados, no podrían ser accedidos desde fuera de la clase,
por lo que la clase no tendría utilidad: no se podría modificar ni el radio de
un círculo.

 Invocar atributos y procedimientos:

Circle c = new Circle(); // c es un objeto


[Link] = 3;
double Area_de_c = [Link]();

77

Ejemplo de Clase: Punto (2D), aplicación de consola

class Punto {
private double x, y; // Coordenadas de cada punto 2D (privadas)
// Escribe el cuadrante donde está un punto Observe cómo se
public void EscribirCuadrante() {
if (x > 0 && y > 0) [Link]("Primer cuadrante."); crea un objeto
else if (x < 0 && y > 0) [Link]("Segundo cuadrante."); de una clase:
else if (x < 0 && y < 0) [Link]("Tercer cuadrante.");
else if (x > 0 && y < 0) [Link]("Cuarto cuadrante.");
else [Link]("No está en un cuadrante.");
[Link](); // Pulsar tecla
}
// Inicializa a cero las coordenadas class Program {
public void Inicializar_a_cero() { static void Main(string[] args) {
x = y = 0; Punto punto1 = new Punto(); //Creación
} punto1.Inicializar_a_cero();
// Pide un punto al usuario [Link](4, -5);
public void Inicializar() { [Link]();
string linea; }
[Link]("Dame la coordenada x :"); }
linea = [Link](); Imprime: Cuarto cuadrante.
x = [Link](linea);
[Link]("Dame la coordenada y :");
linea = [Link](); 1. Los atributos son private, i.e., NO pueden ser
y = [Link](linea); accedidos desde fuera de la clase.
} - En Main no podemos hacer: punto1.x = 3;
// Traslada un punto las distancias (x1,y1)
public void Trasladar(double x1, double y1) { 2. Todos los métodos pueden acceder a los atributos.
x = x + x1; 3. Los métodos son public, i.e., SÍ pueden accederse
y = y + y1; desde fuera de la clase, como se hace en Main.
} 4. Se facilitan dos funciones para inicializar un punto.
} 5. Atributos y métodos pueden ser private/public.

78

39
Definir una Clase: Accesibilidad y Constructores

 Es frecuente poner los atributos como privados para evitar que sean
modificados de forma errónea:
 Modificándolos a través de métodos podemos garantizar que sólo se
modifiquen cumplen los requisitos que queramos.
 Los métodos de la clase siempre pueden acceder a los demás métodos y
atributos de dicha clase.
 Los atributos se inicializan automáticamente (a 0, false, o null),
pero si son privados no se les puede dar valor, salvo que se programe un
constructor, que es un procedimiento que se ejecuta cuando se crea un
objeto con new:
 Constructor: Es un método público con el mismo nombre de la clase.
 No es muy útil que sea privado, pues sólo se podrían usar objetos de esa
clase desde métodos de dicha clase.
 No pueden retornar ningún valor (no se pone ni void).
 Si no escribe ningún constructor, el compilador genera uno por defecto que
no haga nada.
 Constructor default: Aquél que no tiene argumentos.
 Sobrecargar constructores: Puede programar varios constructores con
distintos argumentos, además del constructor default.
 Se ejecutará el constructor que tenga el mismo número y tipo de sus
argumentos.
 Si define un constructor, C# no genera ninguno por defecto:
 Si además desea un constructor default sin argumentos, tendrá que
declararlo explícitamente. 79

Definir una Clase: Accesibilidad y Constructores

 Ejemplo, con dos constructores sobrecargados:


class Circle
{ private int radio;
public Circle() // Constructor default (SIN tipo de retorno)
{ radio = 0;
}
public Circle(int radioinicial) // Constructor sobrecargado (también sin tipo)
{ radio = radioinicial;
}
public void NuevoRadio(int radionuevo) // No es constructor: Requiere TIPO
{ radio = radionuevo;
}
public double Area()
{ return [Link] * radio * radio;
}
}
...
Circle a = new Circle(5), c = new Circle(); // Dos objetos
[Link]("Area del círculo por defecto: " + [Link]());
[Link](6);
[Link]("Area del círculo de radio 6: " + [Link]());
[Link]("Area del círculo de radio 5: " + [Link]());
80

40
Ejemplo: Clase Mamífero
class Mamifero
{
int num_patas, vidas; // Son privados por defecto
bool acuatico;

// Constructor que asigna tres valores:


public Mamifero(int patas, int num_vidas, bool acu)
{
num_patas = patas;
vidas = num_vidas;
acuatico = acu;
}
public void muere()
{
vidas--;
}
public bool vive()
{
return vidas > 0;
}
}
81

Ej.: Subclase Gato • La clase derivada hereda las


propiedades de la clase base.

(o clase derivada) • Es posible agregar o reemplazar


métodos y propiedades según sea
necesario.
class Gato:Mamifero
{ String color_pelo; // Característica propia de los Gatos
// Constructor que asigna el color, 4 patas, 7 vidas, y No acuático:
public Gato (String color):base(4,7,false)
{
• El constructor de la clase base se
color_pelo=color; ejecuta antes que el constructor de la
clase derivada.
}
• Si la clase base tiene más de un
// Más métodos de los Gatos... constructor, la clase derivada puede
decidir a qué constructor se va a
} llamar, y también facilitar los
argumentos del constructor, usando la
palabra clave base.

class Aplication • Vinculación dinámica: La variable animal es de


clase Mamifero y se instancia de clase Gato.
{ static void Main() • El método vive() está definido en la clase Mamifero, y
{ la clase Gato lo tiene por herencia.

Mamifero animal = new Gato("Pardo");


[Link](); // Se quita una vida al Gato "Pardo"
if ([Link]()) [Link]("Sigue vivo!");
}
} 82

41
Métodos y atributos static
 En C# todos los procedimientos deben definirse dentro de una clase,
pero no siempre se requiere una instancia para llamarlos.
 Ej.: La clase Math tiene definidos procedimientos y atributos que pueden usarse
sin declarar ningún objeto de la clase Math.
 [Link], [Link], [Link], [Link], [Link], [Link]...

 Métodos y atributos static: Son aquellos que son útiles sin necesitar
que se ejecuten sobre una instancia previamente creada.
 Para acceder a ellos se usa el nombre de la clase: <Clase>.<Atributo/Método>
 Métodos static sólo pueden acceder a otros métodos y atributos
static.
 Los métodos de instancia (no static) requieren crear primero una instancia.
 Atributos static son compartidos entre todos.
 Los atributos no static son locales para cada instancia de su clase.
 Deben ser inicializados. Ej.: private static int objectCount = 0;
 Es una variable private static para contar los objetos se crean. Habría que
incrementar ese atributo en cada procedimiento constructor (debe ser private
para asegurar que nadie más cambia su valor). Para acceder a su valor desde
fuera, se debe crear un procedimiento public static, que devuelva el valor.
 Si el valor es constante es mejor definirlo con const.
 Las contantes con const son también static.

 Ej.: En Math, PI se define así: public const double PI = 3.14159265358979323846;

83

Palabra clave this


 La palabra clave this es una variable predefinida
disponible en funciones miembro no estáticas:
 Significa "El atributo o procedimiento de este objeto".
 Se usa para acceder a datos y funciones miembro de una clase sin ambigüedad.
 Ej: Si existen argumentos con el mismo nombre que un atributo de la clase.

Usamos this para distinguir el atributo del


class Persona { argumento, porque se llaman igual.
string nombre;
public Persona(string nombre) { Comparamos que el
[Link] = nombre; objeto que se pasa por
} argumentos es distinto al
public void PresentarA(Persona p) { que recibe la llamada.
if (p != this)
[Link]("Hola, soy " + nombre);
else
[Link]("No me presentaré a mí mismo.");
}
}
...
Persona p1 = new Persona("Pepe"),
p2 = new Persona("Juan"), p3;
p3=p1;
[Link](p2); // Se presenta Pepe
[Link](p1); // No se presenta
[Link](p3); // Tampoco se presenta
84

42
Parámetros ref y out
 Paso de argumentos ordinario es por valor:
 El procedimiento trabaja con una copia del valor.
 Ejemplo:
static void Algo(int argumento)
{ argumento++;
}
static void Main()
{ int x=8;
Algo(x);
[Link](x); // Escribe 8
}

 Si pasa un tipo de referencia (un objeto):


 Pueden cambiarse los atributos del objeto del argumento.
 No puede modificarse el argumento en sí, para que almacene
otro objeto diferente.
85

Parámetros ref y out


 Paso por Referencia (ref):
 Hace que el argumento formal sea una referencia al
argumento actual, y ambos referencian al mismo objeto.
 Palabra clave ref en la definición y en la llamada al
procedimiento: Indica que el argumento puede cambiar.
 Ejemplo:
static void Algo(ref int argumento)
{ argumento++;
}
static void Main()
{ int x=8;
Algo(ref x);
[Link](x); // Escribe 9
}

 En el ejemplo, si la variable x no se inicializa, se genera un


error de compilación, ya que interpreta que x es un argumento
tanto de entrada como de salida.
86

43
Parámetros ref y out
 Paso por Referencia, sólo de Salida (out):
 Si un argumento es sólo de salida no tiene sentido que se le obligue a
que tenga un valor antes de invocar al procedimiento.
 Palabra clave out en la definición y en la llamada al
procedimiento: Indica que el argumento debe cambiar en el
procedimiento y si no lo hace se genera un error de compilación.
 Ejemplo:
static void Algo(out int argumento)
{ argumento = 7;
}
static void Main()
{ int x; // OJO: No inicializado
Algo(out x);
[Link](x); // Escribe 7
}

 Puede usar los modificadores ref y out con tipos referencia y tipos
valor, con el mismo efecto: Si reasigna el argumento formal a otro
objeto, el argumento actual de la llamada será otro objeto. 87

Incluir una nueva Ventana (Formulario WPF)

 Primero hay que definirla y luego llamarla:


 Menú Proyecto  Agregar Ventana: Se abre el cuadro de
diálogo “Agregar nuevo elemento”, en el que se debe elegir:
 Plantilla: “Ventana (WPF)”.
 Escribir un <Nombre> adecuado al contenido de esa ventana:
 Se crearán automáticamente los ficheros <Nombre>.xaml y

<Nombre>.[Link] en el proyecto (pueden verse en el


Explorador de Soluciones).
 Diseñar la ventana <Nombre>.xaml, insertando controles,
código C#, etc.
 Abrir la ventana: Insertar, en el código de cualquier otra
ventana (siendo Window2 el <Nombre> de la ventana):
 Una ventana WPF es una subclase de [Link]:
Primero hay que crear una instancia con new, y luego mostrarla:
La clase Window2, se
define en el fichero Window2 ventanaNueva = new Window2();
[Link],
en el namespace de [Link]();
la aplicación.
88

44
C# incluye muchos más Controles
 ComboBox: Para mostrar datos en un cuadro
desplegable, aunque permite al usuario escribir un
elemento de la lista.
 Los elementos se añaden en la propiedad “Items”:
 Image: Para añadir una imagen al formulario.
 La propiedad “Source” indica el fichero de la imagen.
 CheckBox: Permite seleccionar o no un elemento.
 La propiedad “IsChecked” indica si está o no seleccionado.
 Toma 2 ó 3 valores, según la propiedad “IsThreeState” (true, false, y null).
 GroupBox: Control que muestra un marco alrededor
de un grupo de controles con un título opcional.
 TabControl: Administra un conjunto relacionado de
páginas de fichas.

 RichTextBox: Control para texto enriquecido que admite texto


con formato, hipervínculos, imágenes, distintos tipos de letra…
 Menu: Para crear un menú. Las opciones son una colección que se
crea en la propiedad “Items”:
 Se debe poner el texto en “Header”, el nombre en “Name” y la función a
ejecutar en “Click” (usar XAML para algunas propiedades y eventos).
 Más ayuda: [Link]  Usar el buscador 89

Añadir controles Windows Forms a WPF


 Usando WPF, a veces es útil insertar controles de la vieja biblioteca de
Windows Forms. Para ello:
 En el Explorador de soluciones agregar dos referencias: Clic con el botón
derecho sobre la carpeta References, elegir Agregar referencia, y seleccionar
[Link] y WindowsFormsIntegration.
 En el panel XAML añadir una línea para incluir los tipos de Windows Forms, con
el alias wf (línea en negrita):

<Window x:Class="Nacimiento.Window1"
xmlns="[Link]
xmlns:x="[Link]
xmlns:wf="clr-namespace:[Link];assembly=[Link]"
Title="Window1" Height="300" Width="300">

 Generar solución (F6): Esto es necesario para resolver las referencias al


espacio de nombres [Link], antes de añadir los controles.
 Añadir control WindowsFormsHost para que contenga el control de Windows
Forms (por ejemplo, un control DateTimePicker), y cambie su nombre en el
panel de Propiedades (o en XAML).
 En el panel XAML, dentro de WindowsFormsHost, añadir lo siguiente,
cambiando el delimitador de cierre /> por el carácter >, y luego cerrar al final:

<WindowsFormsHost Margin="41,94,37,0" Name="FechaNacimiento" ... >


<wf:DateTimePicker Name="FechaNacimiento"/>
</WindowsFormsHost>
90

45
Ej: Fecha de Nacimiento (aplicación WPF)

 Programa para comprobar si dada una fecha de


nacimiento, es o no su cumpleaños:
 Añadir control DateTimePicker y un botón Comprobar:
private void Comprobar_Click(object sender, RoutedEventArgs e)
{
[Link] fecha =
[Link] as [Link];
if ([Link] == [Link])
[Link]("Felicidades");
else
[Link]("Hoy no es tu cumple");
}
Para acceder al objeto del contenedor,
Si da problemas por ambiguedad, quitar: referenciamos la propiedad Child y lo
using [Link]; convertimos en un tipo adecuado

 La propiedad [Link] tiene subpropiedades diversas: Day


(día del mes), DayOfWeek (día de la semana), Month, Year,
TimeOfDay, Hour, Minute, Second... y también métodos tales
como AddDays, AddMonths, AddYears... 91

46

También podría gustarte