Escolar Documentos
Profissional Documentos
Cultura Documentos
Contenido
1 C sharp NET
o 1.1 El lenguaje C#
o 1.2 Tabla de Contenidos
o 1.3 Pre-requisitos necesarios para este curso
o 1.4 Autores
o 1.5 Licencia
o 1.6 Referencias
2 Capítulo 0
3 Una Breve Introducción a los Lenguajes de Programación
4 Capítulo 1
5 Introducción
o 5.1 La plataforma .NET
5.1.1 Independencia de lenguaje
5.1.2 Librería de clases común
5.1.3 Multiplataforma
5.1.4 Windows Forms, Web Forms, Web Services
5.1.5 Estandarización
o 5.2 Un resúmen introductorio sobre el lenguaje C#
5.2.1 C# frente a Java
5.2.2 C# frente a C++
5.2.3 ¿Por qué C#?
o 5.3 Instalando lo necesario para empezar
6 Capítulo 2
7 Primer programa
o 7.1 Primer programa ¡Hola Mundo!
o 7.2 Comentarios
o 7.3 Clases, Objetos y tipos
o 7.4 Métodos o Funciones
7.4.1 Crear nuevos métodos o funciones
o 7.5 Aplicaciones de consola
o 7.6 Namespaces
o 7.7 La palabra clave using
o 7.8 Caracteres sensibles
8 Capítulo 3
9 Fundamentos del lenguaje
o 9.1 Tipos
9.1.1 Importancia de los tipos de datos
9.1.2 Tipos en C#
9.1.3 Tipos básicos o internos
9.1.4 Escogiendo qué tipo usar
9.1.5 Enteros
9.1.6 Tipos de coma flotante
9.1.7 El tipo decimal
9.1.8 El tipo bool
9.1.9 El tipo char
9.1.10 Tipo Cadenas
9.1.11 Convirtiendo tipos
o 9.2 Arreglos
o 9.3 Identificadores, Variables, Constantes y Enumeraciones
9.3.1 Identificadores
9.3.2 Variables
9.3.3 Constantes
9.3.4 Enumeraciones
o 9.4 Operadores
9.4.1 Operadores matemáticos
9.4.2 Operadores de asignación
9.4.3 Operadores de comparación
9.4.4 Operadores lógicos
9.4.4.1 AND
9.4.4.2 OR
9.4.4.3 NOT
9.4.4.4 XOR
9.4.4.5 <<
9.4.4.6 >>
9.4.5 Operadores lógicos de unión
10 Capítulo 4
11 Estructuras de control
o 11.1 Saltos incondicionales
11.1.1 La sentencia goto
o 11.2 Saltos condicionales
11.2.1 Instrucción if
11.2.2 Instrucción switch
11.2.3 Bucle for
11.2.4 Bucle while
11.2.5 Bucle do-while
11.2.6 Bucle foreach
11.2.7 Usando continue y break
12 Capítulo 5
13 Introducción a las clases y objetos
o 13.1 Introducción a las clases en C#
13.1.1 Métodos
13.1.2 Pasando valores a los métodos
13.1.2.1 Parámetros
13.1.2.2 Paso por valor
13.1.2.3 Paso por referencia
13.1.2.4 Parámetro de salida
13.1.2.5 Arreglo de parámetros
13.1.3 Modificadores public y static
13.1.4 Constructores e instancias de una clase
13.1.5 Sobrecarga de métodos
13.1.6 La palabra reservada this
o 13.2 Propiedades e indizadores
13.2.1 Propiedades
13.2.2 Indexadores
14 Capítulo 6
15 Herencia y Polimorfismo
o 15.1 Herencia
15.1.1 La palabra reservada base
15.1.2 Clases Abstractas
15.1.3 Miembros virtual
15.1.4 Problemas propuestos
16 Capítulo 7
17 Sobrecarga de operadores
o 17.1 ¿Qué es la sobrecarga de operadores?
o 17.2 Sobrecargando operadores en la práctica
o 17.3 Operadores binarios
o 17.4 Operadores Unarios
18 Capítulo 8
19 Estructuras
o 19.1 Rendimiento
20 Capítulo 9
21 Interfaces
o 21.1 Definición
o 21.2 Obteniendo Referencias a la Interfaz
o 21.3 Pasar interfaces como parámetros
o 21.4 Implementación Explícita de una Interfaz
o 21.5 Jerarquías de interfaces
22 Capítulo 10
23 Estructuras de datos
o 23.1 Enumeraciones
o 23.2 Estructuras
24 Capítulo 11
25 Capítulo 12
26 Manejo de excepciones
27 Capítulo 13
28 Delegación y Eventos
o 28.1 Programando con delegados
28.1.1 Llamadas a múltiples métodos
28.1.2 Ejemplo de uso de delegados
29 Capítulo 14
30 Capítulo 15
31 Capítulo 16
32 Capítulo 17
33 Programando aplicaciones WEB con ASP.NET usando C#
34 Capítulo 18
35 Capítulo 19
36 XML
o 36.1 Conceptos básicos de XML
o 36.2 XML en .Net
o 36.3 Escribir un archivo XML
37 Capítulo 20
38 Capítulo 21
39 Capítulo 22
40 Programando en Redes
41 Capítulo 23
42 Capítulo 24
43 Capítulo 25
44 Capítulo 26
45 Utilizando Bases de Datos
o 45.1 Diferencias entre ADO y ADO.NET
o 45.2 ADO.NET a grandes rasgos
46 Capítulo 27
47 Capítulo 28
48 Manejo de puertos con Mono y C#
o 48.1 Introducción
o 48.2 Limitaciones
48.2.1 Código de ejemplo
o 48.3 Puntos a considerar
o 48.4 Links relacionados
49 Capítulo 29
50 Sockets
o 50.1 Introducción a los Sockets
o 50.2 Sincrónico y Asincrónico
o 50.3 Clase Socket
o 50.4 Servidor
o 50.5 Cliente
51 GNU Free Documentation License
o 51.1 0. PREAMBLE
o 51.2 1. APPLICABILITY AND DEFINITIONS
o 51.3 2. VERBATIM COPYING
o 51.4 3. COPYING IN QUANTITY
o 51.5 4. MODIFICATIONS
o 51.6 5. COMBINING DOCUMENTS
o 51.7 6. COLLECTIONS OF DOCUMENTS
o 51.8 7. AGGREGATION WITH INDEPENDENT
WORKS
o 51.9 8. TRANSLATION
o 51.10 9. TERMINATION
o 51.11 10. FUTURE REVISIONS OF THIS LICENSE
C sharp NET
El lenguaje C#
Los primeros rumores de que Microsoft estaba desarrollando un nuevo
lenguaje de programación surgieron en 1998, haciendo referencia a un
lenguaje que entonces llamaban COOL y que decían era muy similar a Java.
En junio de 2000, Microsoft despejó todas las dudas liberando la
especificación de un nuevo lenguaje llamado C#. A esto le siguió rápidamente
la primera versión de prueba del entorno de desarrollo estándar (SDK) .NET,
que incluía un compilador de C#. El nuevo lenguaje estaba diseñado por
Anders Hejlsberg ( creador de Turbo Pascal y arquitecto de Delphi ), Scott
Wiltamuth y Peter Golde. Entonces describieron el lenguaje como "...simple,
moderno, orientado a objetos, de tipado seguro y con una fuerte herencia de
C/C++".
Tabla de Contenidos
Autores
Lenguajes de Programación.
Pocos años despúes de esos días existían personas (y hasta ahora existen
aquellos) que pueden "hablar con el ordenador", se trata de informáticos que
en su época solo disponían de elementos de muy bajo nivel para controlar el
computador, eso hasta el día de hoy es la base de las técnicas de cómputo,
independientemente de cuanto hayan aumentado las capacidades de
memorias, velocidades de microprocesadores, miniaturizaciones, etc.
Llave para arriba ---> ENCENDIDO Llave hacia abajo ---> APAGADO
Así que ahora tenemos algo como un lenguaje elemental para dar indicaciones,
donde tenemos dos instrucciones:
Instrucción: ENCENDIDO............. Equivale a: 1
Añadir más para ilustrar sobre el lenguaje binario (bajo nivel) y los lenguajes
de alto nivel**** (en construcción)
Para poder dominar un lenguaje de programación (al igual que con los
lenguajes naturales) se requiere mucho estudio pero por sobre todo
muchísima práctica. Una persona podría leer este manual unas 500 veces pero
si no pone en práctica los conceptos ni investiga por su cuenta, jamás llegará
a dominar este maravilloso lenguaje de programación. Así que: ¡a practicar se
ha dicho!
[*] Al sistema numérico compuesto únicamente por los elementos "0" y "1"
se le llama Sistema Numérico Binario, o popularmente Sistema Binario.
Capítulo 1
Introducción
La plataforma .NET
Independencia de lenguaje
Todos los lenguajes que conformen con los estándares .NET, sin importar
cual, podrán interoperar entre sí de forma totalmente transparente, las clases
podrán ser heredadas entre unos lenguajes y otros, y se podrá disfrutar de
polimorfismo entre lenguajes. Por ejemplo, si yo tengo una clase en C#, esta
clase podrá ser heredada y utilizada en Visual Basic o JScript o cualquier
lenguaje .NET. Todo esto es posible por medio de una de las características
de .NET llamado Common Type System (CTS). También tiene la cualidad
de que se pueden incluir más lenguajes a la plataforma. En la actualidad
existen proyectos independientes de incluir PHP, Python, Ada y otros
lenguajes en la plataforma.
El CRL
Estandarización
Además de los méritos técnicos, una de las razones del éxito de la plataforma
.NET ha sido por el proceso de estandarización que Microsoft ha seguido (y
que ha sorprendido a más de uno). Microsoft, en lugar de reservarse todos
los derechos sobre el lenguaje y la plataforma, ha publicado las
especificaciones del lenguaje y de la plataforma, que han sido posteriormente
revisadas y ratificadas por la Asociación Europea de Fabricantes de
Computadoras (ECMA). Esta especificación (que se puede descargar
libremente de Internet) permite la implementación del lenguaje C# y de la
plataforma .NET por terceros, incluso en entornos distintos de Windows.
Mono Hispano mantiene una traducción del estándar que describe el lenguaje
C# en http://monohispano.org/ecma/ (Enlace roto)
C# frente a Java
C# frente a C++
La plataforma .NET acepta varios lenguajes. Por ahora, C#, Visual Basic,
C++ gestionado, Nemerle, FORTRAN, Java, Python, etc. , y con capacidad
para aceptar prácticamente cualquier lenguaje. Entonces la pregunta es,
¿porqué se eligió C# en lugar de cualquier otro lenguaje?.
Para poder empezar con nuestro curso debéis tener instalado en vuestro
ordenador los archivos básicos para poder compilar y ejecutar vuestros
programas. El conjunto de utilidades "Microsoft .NET Framework" y el
".NET Framework SDK" para Windows y el proyecto MONO o dotGNU
para Linux, MacOS, BeOS proporcionan estas herramientas. Podréis
encontrarlas en las siguientes direcciónes:
Para Windows:
http://msdn.microsoft.com/netframework/downloads/updates/default.as
px (no se encuentra la pagina
Proyecto Mono
http://mono-project.com/Downloads (manual que describe distintos
métodos de instalación)
Proyecto dotGNU
http://dotgnu.org/pnet-packages.html
Capítulo 2
Primer programa
csc Programa.cs
con MONO:
mono Programa.exe
con dotGNU:
ilsrun Programa.exe
O en Windows:
Programa
class HolaMundo
{
static void Main()
{
string var="Mundo";
System.Console.WriteLine ("Hola {0}!", var);
}
}
Comentarios
Los comentarios de varias líneas sirven para incluir muchas líneas de texto o
código como un comentario. Tienen una marca de inicio que dice cuando
empieza el comentario y una marca que indica el final de dicho comentario.
La marca de inicio es /* y la marca para finalizar es */ Así por ejemplo
tenemos:
/*
este comentario
abarca varias lineas
*/
class HolaMundo
{
static void Main()
{
string var="Mundo";
System.Console.WriteLine ("Hola {0}!", var); //Este comentario
puede describir lo que esta función hace
//System.Console.WriteLine ("y esta linea no la vamos a desplegar");
}
}
Métodos o Funciones
Los métodos o funciones son trozos de código que realizan una acción, esto
es, toman unos argumentos y devuelven un valor. En C#, las funciones deben
ser declaradas dentro de un objeto, normalmente dentro de una clase.
entorno: static
tipo_a_retornar: void
Nombre_de_la_Función: Main
Argumentos: ninguno
namespace Programa1
{
class HolaMundo
{
static void Main()
{
string var="Mundo";
System.Console.WriteLine ("Hola {0}!", var);
int num1 = 1;
int num2 = 3;
int resultado = Suma (num1, num2);
System.Console.WriteLine ("{0}+{1} = {2}", num1, num2,
resultado);
}
Hola Mundo!
1+3=4
Aplicaciones de consola
Las aplicaciones de consola no poseen una interfaz gráfica, no tienen botones
o ventanas, poseen una interfaz basada simplemente en texto. El ejemplo que
hemos realizado hasta ahora es una aplicación de consola que despliega texto
en la pantalla, para ello hemos utilizado la función WriteLine.
Namespaces
Primaria.Presidente.nombre_de_la_función();
Y
Secundaria.Presidente.otra_función();
Algo importante que debemos notar es que los espacios de nombres pueden
tener sub-espacios de nombres y estos a su vez sub-espacios de nombres. El
objetivo de esto, como lo hemos dicho, es mantener una organización de los
componentes. Los espacios de nombres, componentes y métodos se accederán
de la misma forma como lo hemos visto a través de un punto.
La palabra clave using
using System;
namespace Programa1
{
class HolaMundo
{
static void Main()
{
string var="Mundo";
Console.WriteLine ("Hola {0}!", var);
int num1 = 1;
int num2 = 3;
int resultado = Suma (num1, num2);
Console.WriteLine ("{0}+{1} = {2}", num1, num2, resultado);
}
static int Suma(int valor1, int valor2)
{
return valor1+valor2;
}
}
}
Comparando con nuestro ejemplo 2.2 original se ve en el ejemplo que ya no
es necesario poner la palabra system.Console.WriteLine, quedando
Console.WriteLine
Algo importante para tener en cuenta es que la palabra clave using no puede
ser utilizada para ahorrarse el escribir el nombre de la clase. Por ejemplo la
línea de código using System.Console es inválida y producirá errores de
compilación.
Caracteres sensibles
En este capítulo cubriremos lo que son los tipos. Hablaremos de tipos básicos
o internos y de cómo crear nuevos tipos. También hablaremos en general de
la manipulación de datos. Hablaremos sobre condicionales, operadores
matemáticos y varios otros temas relacionados. Empecemos entonces nuestro
estudio con lo que son tipos.
Tipos
Tipos en C#
'Los tipos en C# al igual que C++ y Java se clasifican en dos secciones: Tipos
básicos o internos y tipos creados por el usuario. Los tipos básicos no son
más que alias para tipos predefinidos en la librería base de la plataforma
.NET. Así, el tipo número entero (que se representa con la palabra clave int),
no es más que una forma rápida de escribir System.Int32.
Dentro de estas dos secciones los tipos del lenguaje C# también son divididos
en dos grandes categorías: tipos por valor y tipos por referencia. Existe una
tercera categoría de tipos, disponible solo cuando se usa código no seguro:
los punteros, que se discutirán más adelante cuando hablemos de los objetos
COM.
Los tipos por valor difieren de los tipos por referencia en que las variables de
los tipos por valor contienen directamente su valor, mientras que las variables
de los tipos por referencia almacenan la dirección donde se encuentran los
objetos, es por eso que se las llaman referencias. Más adelante describiremos
como funcionan cada una de estas categorías.
Nombre para la
Tipo Con Bytes
plataforma Valores que soporta
C# signo? utilizados
.NET
true o false (verdadero o falso en
bool System.Boolean No 1
inglés)
byte System.Byte No 1 0 hasta 255
sbyte System.SByte Si 1 -128 hasta 127
short System.Int16 Si 2 -32.768 hasta 32.767
ushort System.Uint16 No 2 0 hasta 65535
-2.147.483.648 hasta
int System.Int32 Si 4
2.147.483.647
uint System.Uint32 No 4 0 hasta 4.394.967.395
-9.223.372.036.854.775.808
long System.Int64 Si 8 hasta
9.223.372.036.854.775.807
0 hasta
ulong System.Uint64 No 8
18446744073709551615
Approximadamente ±1.5E-45
float System.Single Si 4 hasta ±3.4E38 con 7 cifras
significativas
Approximadamente ±5.0E-324
double System.Double Si 8 hasta ±1.7E308 con 7 cifras
significativas
Approximadamente ±1.0E-28
decimal System.Decimal Si 12 hasta ±7.9E28 con 28 ó 29
cifras significativas
Cualquier carácter Unicode (16
char System.Char 2
bits)
C# tiene una ventaja y característica especial sobre los demás lenguajes de
programación modernos y es que cada vez que se crea un objeto de un tipo
básico, éstos son mapeados internamente a un tipo primitivo de la plataforma
.NET el cual es parte del CLS (Especificación común del lenguaje) lo cual
nos permite acceder y hacer uso de estos desde cualquier lenguaje de la
plataforma .NET. Es decir si es que creamos un objeto de tipo int (entero)
en C#, ese objeto podrá ser usado como tal dentro de J#, JScript, Visual
Basic .NET y cualquier otro lenguaje que conforme los requisitos de .NET.
Por ejemplo en nuestro ejemplo 2.2 del capítulo anterior necesitábamos hacer
la suma de dos valores numéricos por lo que usamos dos tipos básicos de
número entero (usando la palabra clave int) los cuales de acuerdo con nuestra
tabla 3.1 son números enteros (no pueden llevar valores decimales) y podrán
aceptar valores entre -2,147,483,648 y 2,147,483,647 lo cual es más que
suficiente para nuestro ejemplo de añadir dos números.
Enteros
Los tipos que sirven para almacenar números enteros son: byte, sbyte. short,
ushort, int, uint, long y ulong. Como se aprecia en la tabla, C# define
versiones con y sin signo para tipos con los mismos bytes utilizados. Cada
tipo se distingue por la capacidad de almacenaje.
Los tipos de coma flotante sirven para representar a números con parte
fraccionaria. La representación por supuesto puede no ser exacta, bien por
errores de la máquina, bien porque el número de decimales que se puede alojar
es finito.
Existen tres clases de tipos de punto flotante : float, double y decimal. De los
dos, el más usado es double, pues es el valor que devuelven la mayoría de las
funciones matemáticas de la librería base.
class Flotante{
public static void Main()
{
int a = 2;
double log2 = Math.Log(a);
double raiz2 = Math.Sqrt(a);
Console.WriteLine("El logaritmo de dos es {0}", log2 );
Console.WriteLine("La raiz de dos es {0}", raiz2 );
}
}
El tipo decimal
El tipo bool
b es True
esto saldrá
2==2 es True
El tipo char
\' apostrofe
\" Comillas
\\ Backslash
\0 Null (nulo)
\a Alerta
\b Retroceso
\f Form feed
\n Línea nueva
\r Retorno del carro
\t Tabulación Horizontal
\v Tabulación Vertical
Tipo Cadenas
Los tipos cadena (palabra clave string) son tipos que almacenan un grupo de
caracteres. En C# los tipos cadena se crean con la palabra clave string seguido
por el nombre de la variable que deseamos instanciar. Para asignar un valor a
este tipo debemos hacerlo entre comillas de la siguiente forma:
Debido a que el tipo cadena (string) es uno de los tipos más usados en C#,
lo estudiaremos detalladamente más adelante.
Convirtiendo tipos
short corto = 3;
int entero = corto; //compilará sin ningún problema
aquí sucede una conversión implícita, el valor de la variable corto (en este
caso 3) que es de tipo short es asignado a la variable de tipo int sin que el
compilador nos de ningún problema ya que hará una conversión de short a
int implícitamente por nosotros debido a la regla anteriormente citada.
En el caso que queramos hacer de forma inversa, es decir asignar un valor int
a una variable short, estaríamos violando la regla de asignar un tipo de menor
capacidad a una variable de tipo de mayor capacidad aunque sean de la misma
clase (enteros). Así el siguiente ejemplo no compilará dándonos un error:
Arreglos
using System;
class Arreglo{
public static void Main()
{
int[] arr = new int[3];
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
Console.WriteLine( arr[1] );
}
}
Existe una forma más corta para declarar el arreglo y asignarle los valores:
using System;
class Arreglo2{
public static void Main()
{
int[,] arr = new int[2,2];
arr[0,0] = 1;
arr[1,0] = 2;
arr[0,1] = 3;
arr[1,1] = 4;
Console.WriteLine("El valor que posee la variable arr[1,1] es {0}",
arr[1,1] );
}
}
el resultado será:
Identificadores
Ejemplo:
EsteIdentificadorEsValido
_este_también
esteEsOtro1
esteEsOtro2
Esto es invalido
123_Otro_inválido
int
Variables
Para crear una variable debemos especificar a qué tipo pertenece antes del
nombre que le vamos a dar. Por ejemplo si deseamos crear una variable que
se llame var y que sea del tipo entero (int) procederemos de la siguiente
manera:
int var;
var = 10;
Hay que tener presente que la variable como su nombre lo indica podrá tomar
otros valores. Por ejemplo si deseamos que nuestra variable cambie de valor a
5 hacemos lo que habíamos hecho en el ejemplo anterior pero con el nuevo
valor:
var = 5;
Las constantes como su nombre lo indica son variables cuyo valor no puede
ser alterado. Éstas se utilizan para definir valores que no cambian con el
tiempo. Por ejemplo podemos definir una constante para especificar cuantos
segundos hay en una hora de la siguiente forma:
Enumeraciones
using System;
namespace Autos
{
class Control
{
enum tanque
{
lleno,
medio,
bajo,
critico,
}
auto1 = tanque.critico;
RevisarEstadoTanque(auto1);
}
Este programa sencillo crea una enumeración llamada tanque y dentro de ella
crea 4 constantes: lleno, medio, bajo, y critico. Dentro de nuestro programa
creamos la variable de tipo tanque llamada auto1 la cual podrá tomar los
valores especificados dentro de la enumeración. Cuando asignamos a la
variable auto1 el valor de tanque.lleno y revisamos el estado del tanque
llamando a la función RevisarEstadoTanque, podremos comprobar cuál es el
estado actual del tanque de combustible. Ésta es una forma muy descriptiva
de cómo crear variables que cambien de estado, una solución elegante y
sencilla a nuestro problema.
using System;
namespace Ejemplos
{
class Enumeraciones
{
enum segundos :uint
{
minuto = 60,
hora = 3600,
dia = 86400,
}
static void Main()
{
Console.WriteLine("Existen {0} segundos en 1 minuto, {1} segundos
en 1 hora y {2} segundos en 24 horas",(uint)segundos.minuto,
(uint)segundos.hora, (uint)segundos.dia);
}
}
}
El resultado es el siguiente:
El ejemplo anterior nos muestra otra forma de usar una enumeración. Hay
que tener en cuenta que el tipo que va a tener la enumeración se encuentra
después del nombre de la enumeración precedido por dos puntos. De esa
forma podremos especificar de qué tipo son. Como habíamos dicho
anteriormente se podrá utilizar cualquier tipo de la clase enteros como byte,
sbyte, short, ushort, int, uint, long o ulong. En el caso de que no se especifique
a qué tipo pertenece el compilador le dará el tipo int. También se debe tomar
en cuenta que los valores de las constantes están asignados con el signo = y
están separadas por comas.
enum números
{
uno, //toma el valor de 0
dos, //toma el valor de 1
diez = 10, //toma el valor de 10
once, //toma el valor de 11
}
Operadores
Los operadores son símbolos con los cuales C# tomará una acción. Por
ejemplo existen operadores matemáticos para sumar, restar, multiplicar y
dividir números. Existen también operadores de comparación que analizará
si un valor es igual, mayor o menor que otro y operadores de asignación los
cuales asignarán nuevos valores a los objetos o variables. A continuación
explicaremos un poco más detalladamente los operadores en C#:
Operadores matemáticos
using System;
class operadoresMatematicos
{
public static void Main()
{
int a = 7;
int b = 4;
int c = a + b;
int d = a - b;
int e = a * b;
int f = a / b;
int g = a % b;
Console.WriteLine ("De los números: {0} y {1} la suma es: {2},
la resta es:{3}, la multiplicación es: {4}, la división es: {5} con un residuo
de: {6}",a,b,c,d,e,f,g);
}
}
Operadores de asignación
Los operadores de asignación son aquellos que sirven para asignar el valor del
objeto o variable de la derecha al objeto o variable de la izquierda. Un ejemplo
sencillo de este tipo de operadores es la inicialización de variables. Como
habíamos visto, para asignar el valor a una variable simplemente utilizamos el
símbolo (u operador) igual =
Operadores de comparación
Estos operadores son muy útiles cuando tenemos que cambiar el flujo de
nuestro programa. Con ellos podemos comparar si un objeto o variable es
igual (==), no es igual (!=), es mayor o igual (>=), es menor o igual (<=),
es mayor (>) o es menor (<) que otro objeto. El resultado de esta
comparación es de tipo bool es decir verdadero o falso (true o false). Estos
operadores se los usa de la siguiente forma:
int a = 10;
int b = 20;
bool resp;
Operadores lógicos
Para entender como funcionan los operadores lógicos tenemos que aprender
un poco lo que son los números binarios. En esta parte del libro no
cubriremos en detalle este extenso tema de los números binarios ni del
Algebra que gobierna estos números ni mucho menos de como se comportan
las puertas lógicas dentro de un ordenador porque nos tomaría uno o dos
libros completos, pero nos gustaría dar un poco de bases de como es que los
números binarios forman parte de los operadores lógicos. Toda información
que el ordenador opera internamente es representada por números binarios
(por unos y ceros que son conocidos también por verdadero y falso), así la
letra A el ordenador internamente lo representa en código binaro ASCII
como 01000001 que en números "normales" o decimales es 65. Para
manipular esta información en unos y ceros, el ordernador tiene operadores
lógicos los cuales permiten cambiar la información de una manera que nos
convenga. Por medio de estos operadores lógicos el ordenador es capaz de
tomar decisiones, procesar cualquier información, hacer complicadas
operaciones matemáticas, o en otras palabras, por medio de estos operadores
lógicos, el ordenador hace todo lo que vosotros le habéis visto hacer.
AND
OR
NOT
XOR
<<
Desplazar a la izquierda desplaza todos los bits hacia la izquierda
introduciendo ceros al final de la derecha y descartando los últimos números.
Así el número 01000001 si se lo desplaza a la izquierda una vez 01000001
<< 1, se convierte en 10000010
>>
En el caso de que deseemos comparar varios valores para saber si todos son
verdaderos o si alguno es verdadero podemos usar los operadores lógicos de
unión && y ||
int a = 0;
int b = 10;
int c = 20;
Estructuras de control
Saltos incondicionales
using System;
namespace Ejemplos{
class Ejemplo4_1{
static void Main(){
Console.WriteLine ("Esta parte se ejecuta primero");
LlamadaOtraFuncion();
Console.WriteLine ("Esta parte se ejecuta al final");
}
La sentencia goto
using System;
namespace Ejemplos
{
class Ejemplo4_0
{
static void Main()
{
int contador=0;
REPETIR:
Console.WriteLine ("Esta línea se repetirá 100 veces, esta es la linea
numero: {0}", contador);
if (contador++ < 100)
goto REPETIR;
Console.WriteLine ("Despues de que el contador sea igual o
mayor que 100 se imprimirá esta línea");
}
}
}
Saltos condicionales
Instrucción if
Esta sentencia sirve para ejecutar unas instrucciones en caso de que se cumpla
determinada condición. La forma completa de la instrucción if es
if( condición ) {
instrucciones;
...
}
else {
instrucciones;
...
}
class InstruccionIf{
Console.WriteLine("Introduce un numero");
d = Double.Parse( Console.ReadLine() );
if( d>0 )
{
Console.WriteLine("El numero {0} es positivo", d);
}
else
{
Console.WriteLine("El numero {0} es negativo", d);
}
}
}
if( condicion1 )
{
instrucciones;
}
else if( condicion2 )
{
instrucciones;
}
...
else
{
instrucciones;
}
using System;
class IfElseIf{
public static void Main()
{
string opcion;
le pide al usuario que elija una opción si/no y la procesa usando una
estructura if-else-if. Si la opción no es ni "si" ni "no", entonces se ejecuta la
sentencia else por defecto, que imprime por pantalla el mensaje "No entiendo
lo que ha escrito"
Nota: Hay que tener mucho cuidado que el símbolo = no es igual a ==, el
primero sirve para asignar un valor a una variable
y el segundo sirve para comparar si dos términos son iguales.
Instrucción switch
switch( expresión ){
case constante1:
instrucciones;
break;
case constante2:
instrucciones;
break;
...
default:
instrucciones;
break;
}
using System;
class InstruccionSwitch{
public static void Main()
{
string s;
s = Console.ReadLine();
switch(s){
case "+":
Console.WriteLine("El resultado es {0}", 2+3);
break;
case "-":
Console.WriteLine("El resultado es {0}", 2-3);
break;
case "*":
Console.WriteLine("El resultado es {0}", 2*3);
break;
case "/":
Console.WriteLine("El resultado es {0}", 2/3);
break;
default:
Console.WriteLine("No te entiendo");
break;
}
}
}
El cual solicita al usuario que inserte uno de los símbolos +-*/ , y con un
switch compara los resultados para hacer diferentes acciones dependiendo del
valor de s, que es la cadena de caracteres que almacena la elección del usuario.
El resultado debería ser algo parecido a esto:
Como habrá notado, al final de todo case siempre hay una sentencia break.
Esto no es obligatorio, puede haber en su lugar otra sentencia de salto como
un goto inclusive en el caso default.
Ejemplo:
using System;
class InstruccionSwitch{
public static void Main()
{
int voto;
Console.WriteLine( "Qué tipo de musica te gusta más");
Console.WriteLine( "1 - Rock" );
Console.WriteLine( "2 - Clásica (clasica cuenta como
instrumental)" );
Console.WriteLine( "3 - Instrumental" );
Console.WriteLine( "4 - Alternativa (alternativo cuenta como
Rock)" );
voto = Int32.Parse(Console.ReadLine());
switch(voto){
case 1:
Console.WriteLine("Has votado por Rock o Alternativo");
break;
case 2: //Debido a que no tiene ni un goto ni break y está vacía
va al siguiente caso
case 3:
Console.WriteLine("Has votado por Clásica o Instrumental");
break;
case 4:
goto case 1;
default:
Console.WriteLine("No te entiendo");
break;
}
}
}
Bucle for
Las sentencias de iteración se ejecutan también cada vez que se realiza una
nuevo ciclo en el bucle, y sirven para cambiar el estado de las variables que
gobiernan las sentencias de condición. Pero todo esto se entiende mejor con
un ejemplo
using System;
class BucleFor{
public static void Main()
{
int i; //el contador
using System;
class BucleFor2{
public static void Main()
{
int i;
int j;
Por su parte, la expresión condicional del bucle for puede ser cualquier
expresión que genere un valor booleano. En este caso se ha usado "i<j", pero
también hubiera sido válida "i==5", "true" (el bucle se realizará
indefinidamente) o "false" (el bucle no se realizará).
Bucle while
while( condición )
{
instrucciones;
}
Donde la condición tiene que ser un valor booleano. Tiene una estructura
muy sencilla, así que vamos a ver directamente un ejemplo.
using System;
class BucleWhile{
public static void Main()
{
int i = 0;
while( i<10)
{
Console.WriteLine( i );
i = i+1;
}
}
}
En el que se realiza lo mismo que en el ejemplo anterior, sólo que ahora con
un bucle while.
Bucle do-while
Se trata de una ligera variante del bucle anterior, con la diferencia de que
ahora primero se ejecutan las instrucciones y luego se evalúa la condición, de
forma que tiene tiene una estructura:
do{
instrucciones;
}
while( condición );
El siguiente ejemplo
using System;
class BucleDoWhile{
public static void Main()
{
string s = "";
do
{
Console.WriteLine( "Introduce si para salir del bucle" );
s = Console.ReadLine();
}
while( s != "si" );
}
}
muestra un programa que ejecuta un bucle hasta que el usuario introduce "si".
Por cierto, != es lo contrario de ==, es decir, != devuelve true cuando los
valores comparados son distintos.
Bucle foreach
using System;
class BucleForeach{
public static void Main()
{
int[,] arr = {{1,2},{2,3}};
Este ejemplo sólo imprime los valores de una matriz, pero como se puede
comprobar mejora mucho la claridad del código comparándolo con una
implementación con bucles for como esta
using System;
class BucleForeach{
public static void Main()
{
int i, j; //seran los indexadores de la matriz
Además, es posible utilizar el bucle foreach con cualquier tipo que sea una
colección, no solo con arreglos, como veremos más adelante.
continue y break son dos palabras clave que nos permiten saltar
incondicionalmente al inicio de un bucle (continue) o fuera de un bucle
(break) cuando se necesite. Por ejemplo:
using System;
class continueBreak
{
public static void Main()
{
for(int i = 0; i<10; i++ )
{
if (i==5)
continue;
if (i==9)
break;
Console.Write("{0},",i);
}
}
}
Este pequeño programa entrará en un bucle for que hará que la variable i tome
los valores del 1 al 10, pero al llegar al número 5 el bucle saltará
incondicionalmente al inicio del bucle sin ejecutar las líneas que siguen más
adelante por lo que no ejecutará la línea que imprime en la pantalla el número
5. Cosa similar sucede cuando llega al número 9: el bucle será detenido por
el salto incondicional break que romperá el bucle cuando encuentre esta
palabra. El resultado será el siguiente:
0,1,2,3,4,6,7,8,
El bucle saltó la línea que imprime 5 y terminó cuando llegó a 9 gracias a las
palabras clave continue y break.
Capítulo 5
Una clase es como una plantilla que describe cómo deben ser las instancias
de dicha clase, de forma que cuando creamos una instancia, ésta tendrá
exactamente los mismos métodos y variables que los que tiene la clase. Los
datos y métodos contenidos en una clase se llaman miembros de la clase y se
accede a ellos siempre mediante el operador ".".
using System;
public int a = 1;
private double b = 3;
public char c = 'a';
}
los identificadores public delante de los tipos que hay dentro de Clase1 son
necesarios para luego poder ser llamados desde otra clase, como en este caso,
que estamos llamando a los miembros de una instancia de Clase1 desde
UsoClase. Pero en las clases no solo hay variables, también podemos incluir
métodos.
using System;
Podemos hacer más cosas con las clases, como heredar otras clases o
implementar interfaces, pero en este capítulo nos centraremos en el uso de
métodos y variables.
Métodos
Los métodos, también llamados funciones, son trozos de código que reciben
unos datos, hacen algo con esos datos, y a veces devuelven algún valor. En
C#, todos los métodos se encuentran contenidos dentro de un objeto.
* Tipo devuelto
* Nombre del método
* Parámetros (puede ser vacío)
* Cuerpo del método
devuelve un tipo double, tiene por nombre Divide, los parámetos son a y b,
ambos del tipo double, y el cuerpo del método es simplemente "return a/b;".
Según lo que hemos visto, el ejemplo del método Divide() completo necesita
tener una clase donde definirse y un método Main() donde ejecutarse.
using System;
class Metodo{
public double Divide( double a, double b )
{
return a/b;
}
}
class Principal{
public static void Main()
{
Metodo m = new Metodo();
Console.WriteLine( m.Divide(8, 2) );
}
}
Parámetros
El paso de parámetros por valor es usado por defecto para pasar parámetros
a métodos. Cuando se pasa un parámetro por valor a una función realmente
se está pasando una copia de dicho parámetro, por lo que las modificaciones
que le hagamos al parámetro dentro del método no afectarán al parámetro
original. El ejemplo
using System;
class Test {
static void F(int p) {
p++;
Console.WriteLine("p = {0}", p);
}
static void Main() {
int a = 1;
Console.WriteLine("pre: a = {0}", a);
F(a);
Console.WriteLine("post: a = {0}", a);
}
}
pre: a = 1
p=2
post: a = 1
aunque el valor del parámetro p haya sido modificado dentro del método,
éste parámetro solamente tenía una copia del valor del parámetro a que
pasamos al método; por lo que cuando imprimimos el parámetro a vemos que
éste parámetro ha mantenido su valor original.
using System;
class Test {
static void Swap(ref int a, ref int b) {
// intercambia los dos valores
int t = a;
a = b;
b = t;
}
static void Main() {
int x = 1;
int y = 2;
pre: x = 1, y = 2
post: x = 2, y = 1
Parámetro de salida
using System;
class Test {
static void Divide(int num1, int num2, out int result, out int resid) {
result = num1 / num2;
resid = num1 % num2;
}
static void Main() {
int valor1 = 10;
int valor2 = 3;
int respuesta, residuo;
Divide(valor1, valor2, out respuesta, out residuo);
Console.WriteLine("La división de {0} para {1} = {2} con un
residuo de {3}", valor1, valor2, respuesta, residuo);
}
}
muestra un método Divide que incluye dos parámetros de salida. Uno para
el resultado (variable result) de la división y otro para el resto (variable resid).
Vemos que estos resultados son asignados a las variables respuesta y residuo
respectivamente.
Arreglo de parámetros
using System;
class Test
{
static void F(params int[] args) {
Console.WriteLine("nº de argumentos: {0}", args.Length);
for (int i = 0; i < args.Length; i++)
Console.WriteLine("args[{0}] = {1}", i, args[i]);
}
static void Main() {
F();
F(1);
F(1, 2);
F(1, 2, 3);
F(new int[] {1, 2, 3, 4});
}
}
int a = 1, b = 2;
Console.WriteLine("a = {0}, b = {1}", a, b);
using System;
namespace System
{
public class Console
{
public static void WriteLine(string s) {...}
public static void WriteLine(string s, object a) {...}
public static void WriteLine(string s, object a, object b) {...}
...
public static void WriteLine(string s, params object[] args) {...}
}
}
using System;
class Metodo{
public double Divide( double a, double b )
{
return a/b;
}
}
class Principal{
public static void Main()
{
Metodo m = new Metodo();
Console.WriteLine( m.Divide(8, 2) );
}
}
Además, tampoco es necesario crear una instancia de la clase sólo para acceder
a un método declarado en ella. Para eso debemos anteponer a la declaración
del método el modificador static. Los métodos estáticos se caracterizan por
no necesitar una instancia de la clase para cumplir su función, pero como
contrapartida, no pueden acceder a datos propios de la clase.
using System;
class Metodo{
public static double Divide( double a, double b )
{
return a/b;
}
}
class Principal{
public static void Main()
{
Console.WriteLine( Metodo.Divide(8, 2) );
}
}
Como hemos visto, las instancias de una clase se crean con la sintaxis
nombreclase objeto = new nombreclase( argumentos );
Una vez creada una clase, sus miembros se inicializan a sus valores
predeterminados ( cero para valores numéricos, cadena vacía para el tipo
string, etc. ). La siguiente clase representa un punto sobre el plano, de forma
que tiene dos valores públicos X e Y, y un método que calcula la distancia al
origen del punto (módulo)
using System;
class Punto{
public double X;
public double Y;
class Principal{
public static void Main()
{
Punto A = new Punto();
A.X = 1;
A.Y = 1;
}
}
using System;
class Punto{
public double X;
public double Y;
class Punto{
public Punto( double val1, double val2)
{
X = val1;
Y = val2;
}
...
}
Sobrecarga de métodos
En C#, al igual que en C++ y en Java es posible definir varios métodos con
el mismo nombre pero con distintos parámetros, de forma que el compilador
decide a cuál se llama dependiendo de los parámetros que le lleguen.
Esto es muy práctico, pues no tienes que renombrar cada función según el
tipo de valor que acepta. El siguiente ejemplo implementa un par de métodos
que elevan al cuadrado el valor que reciben, y se implementan para tipos
double y para int. En C, que es un lenguaje que no soporta sobrecarga de
métodos, se tendría que haber llamado distinto a ambos métodos, por
ejemplo alcuadrado_double y alcuadrado_int
using System;
class Eleva{
public static double AlCuadrado( int a )
{
return a*a;
}
class Principal{
public static void Main()
{
Console.WriteLine("4 al cuadrado es {0}", Eleva.AlCuadrado(4)
);
Console.WriteLine("3.2 al cuadrado es {0}",
Eleva.AlCuadrado(3.2) );
}
}
this.campo
class Complejo
{
double X;
double Y;
Complejo(double X, double Y)
{
this.X = X;
this.Y = Y;
}
}
Propiedades e indizadores
Propiedades
Para los programadores de Java hay que decir que esto no es más que la
formalización del patrón de asignación (setter) y método de lectura (getter)
using System;
class TestProperties {
private static string clave;
public string Clave {
get
{
Console.WriteLine ("Acceso a la propiedad clave");
return clave;
}
set
{
Console.WriteLine ("Cambio del valor de clave");
clave = value;
}
}
}
class Test {
public static void Main () {
TestProperties tp = new TestProperties();
string c = "ClaveClave";
tp.Clave = c;
Console.WriteLine (tp.Clave);
}
}
Indexadores
using System;
class PruebaIndexadores
{
private int[] tabla = {1, 2, 3, 4};
Para probar esta clase, creamos otra clase con un punto de entrada (public
static void Main ()), que será donde hagamos las pruebas.
int a = obj[3];
obj[3] = 6;
a = obj[3];
Capítulo 6
Herencia y Polimorfismo
Herencia
Las clases en C# soportan herencia simple, de forma que una clase puede
derivar de otra, pero no de varias (como si era posible en C++). De hecho,
en C# todas las clases derivan implícitamente de la clase object.
La sintaxis que se utiliza es la siguiente:
using System;
class A{
public void F()
{
Console.WriteLine("Soy F() de A");
}
}
class B : A{
public void G()
{
Console.WriteLine("Soy G() de B");
}
}
class Principal{
public static void Main()
{
B clase_heredada = new B();
clase_heredada.F();
clase_heredada.G();
}
}
base.nombre_del_miembro
class B : A{
public void H()
{
base.F();
Console.WriteLine("soy H() de B");
}
}
Clases Abstractas
Las clases abstractas son clases que contienen algún método incompleto, esto
es, que está definido pero no implementado. Por lo tanto, no se pueden
instanciar y su único propósito es servir de clase base de las que se derivarán
otras clases.
Las clases que heredan una clase abstracta deben implementar los métodos
incompletos. Las clases abstractas se declaran con la palabra reservada abstract
using System;
abstract class A{
public void F(); //metodo no implementado
}
class B : A{
//error en tiempo de compilación, B tiene que definir un método F()
}
Miembros virtual
using System;
class A {
public virtual void F()
{
Console.WriteLine("A.F");
}
}
class B: A {
public override void F()
{
base.F();
Console.WriteLine("B.F");
}
}
class Test {
public static void Main()
{
B b = new B();
b.F();
A a = b;
a.F();
}
}
muestra una clase A con un método virtual F, y una clase B que sobreescribe
F. El método sobreescrito en B contiene una llamada, base.F(), el cual llama
al método sobreescrito en A.
Problemas propuestos
using System;
namespace m7tr1x
{
class Program
{
static void Main(string[] args)
{
Console.Title = "tH3 M7tr1x 3ff3<t";
Console.ForegroundColor = ConsoleColor.DarkGreen;
Console.WindowLeft = Console.WindowTop = 0;
Console.WindowHeight = Console.BufferHeight =
Console.LargestWindowHeight;
Console.WindowWidth = Console.BufferWidth =
Console.LargestWindowWidth;
Console.WriteLine("H1T 7NY K3Y T0 C0NT1NU3 =/");
Console.ReadKey();
Console.CursorVisible = false;
int width, height;
int[] y;
int[] l;
Initialize(out width, out height, out y, out l);
int ms;
while (true)
{
DateTime t1 = DateTime.Now;
MatrixStep(width, height, y, l);
ms = 10 - (int)((TimeSpan)(DateTime.Now -
t1)).TotalMilliseconds;
if (ms> 0)
System.Threading.Thread.Sleep(ms);
if (Console.KeyAvailable)
if (Console.ReadKey().Key == ConsoleKey.F5)
Initialize(out width, out height, out y, out l);
}
}
private static void Initialize(out int width, out int height, out int[] y,
out int[] l)
{
int h1;
int h2 = (h1 = (height = Console.WindowHeight) / 2) / 2;
width = Console.WindowWidth - 1;
y = new int[width];
l = new int[width];
int x;
Console.Clear();
for (x = 0; x <width; ++x)
{
y[x] = r.Next(height);
l[x] = r.Next(h2 * ((x % 11 != 10) ? 2 : 1), h1 * ((x % 11 != 10)
? 2 : 1));
}
}
Sobrecarga de operadores
Los operadores que podemos sobrecargar son los unarios, +, -, !, ~, ++, --;
y los binarios +, -, *, /, %, &, |, ^, <<, >>. Es importante decir que los
operadores de comparación, ==, !=, <, >, <=, >=, se pueden sobrecargar
pero con la condición que siempre se sobrecargue el complementario, es decir,
si sobrecargamos el == debemos sobrecargar el !=.
Sobrecargando operadores en la práctica
// constructor de la clase
public ComplexNum(float real, float img)
{
this.real = real;
this.img = img;
}
// propiedad Real
public float Real{
get{
return real;
}
set{
real = value;
}
}
// propiedad Img
public float Img{
get{
return img;
}
set{
img = value;
}
}
Este método sobrecarga el operador suma para que podamos sumar dos
números complejos. Un dato a tener en cuenta es que los métodos que
sobrecargan operadores deben ser static. Como se ve en el código los
operandos son 'a' y 'b', que se reciben como parámetro y el resultado de la
operación es otro número complejo que es el que retorna el método. Por tanto
se limita a crear un nuevo número complejo con ambas partes operadas. De
la misma forma podemos crear la sobrecarga del operador resta('-') para que
lleve a cabo la misma función:
Operadores Unarios
Como hemos dicho antes, la operación que hagamos dentro del método que
sobrecarga el operador es totalmente libre, se puede poner el ejemplo de
multiplicar dos matrices lo que es mas complejo que sumar dos números
complejos.
Capítulo 8
Estructuras
Por ejemplo, el uso de una estructura más bien que una clase para un Punto
puede producir una gran diferencia en el número de asignaciones producidas
en memoria en tiempo de ejecución. El siguiente programa crea e inicializa
un arreglo de 100 puntos. Con Punto implementado como clase, 101 objetos
separados son inicializados ( uno para el vector y uno para cada uno de los
100 elementos )
class Punto
{
public int x, y;
public Punto(int x, int y) {
this.x = x;
this.y = y;
}
}
class Test
{
static void Main() {
Punto[] Puntos = new Punto[100];
for (int i = 0; i < 100; i++)
{
Puntos[i] = new Punto(i, i*i);
}
}
}
struct Punto
{
public int x, y;
public Punto(int x, int y) {
this.x = x;
this.y = y;
}
}
Capítulo 9
Interfaces
Definición
Seguramente alguien se preguntara por que usar interfaces pudiendo usar una
clase base abstracta definiendo los métodos anteriores como abstractos, la
primera razón es simplicidad, una clase base abstracta suele hacer más que
definir una colección de métodos, es capaz de definir métodos públicos,
privados, protegidos y también metodos concretos (estáticos) a los que
pueden acceder todas las clases que deriven de ella mientras que una interfaz
se limita a definir una colección de métodos sin ninguna implementación. La
segunda razón es que C# solamente soporta herencia simple, pero sin
embargo podemos hacer que una clase implemente múltiples interfaces.
He aquí como haríamos para heredar de una clase base e implementar una
interfaz, teniendo en cuenta que VehiculoDeMotor será nuestra clase base e
IMovil nuestra interfaz.
bool Acelerar(int n)
{
//implementación de Acelerar
}
bool Frenar(int n)
{
//implementación de Frenar
}
}
Hay que tener en cuenta que siempre hay que poner la clase base antes de las
interfaces.
Ahora nuestra clase CocheDeportivo así como cualquier otra clase que
implemente IMovil podra acelerar y frenar, hay que tener en cuenta que si
implementamos IMovil tendremos que implementar absolutamente todos sus
métodos.
Otra forma de hacerlo sin tener que recurrir a la gestión de excepciones sería
utilizando la palabra reservada as de C#:
El segundo método sólo podrá ser llamado si usamos una referencia de tipo
IAltaVelocidad mientras que el primero podrá ser llamado usando una
referencia a Campeon o a Formula1 (su clase base).
Existen algunas reglas extra al hacer esto, por ejemplo no podemos usar
modificadores de accesibilidad (public, private, protected) ya que si
intentamos que sólo se pueda acceder al método desde una referencia a la
interfaz hacerlo sería contraproducente.
También hay que tener en cuenta que pueden haber colisiones de nombres
entre clases base e interfaces y entre interfaces entre sí, técnicamente no existe
ninguna diferencia y todas pueden ser tratadas como hemos explicado arriba.
Jerarquías de interfaces
Las interfaces pueden servir de base para otras interfaces al igual que las clases,
e igual que en éstas la idea es que vayamos de lo general a lo particular.
Por ejemplo:
interface IVehiculo
{
void Acelerar();
void Frenar();
}
interface IVehiculoGasolina : IVehiculo
{
void CambiarVelocidadInyeccion(int velocidad);
}
interface IVehiculo4x4: IVehiculoGasolina
{
void Activar4x4(bool activar);
}
void IVehiculo.Acelerar(int n)
{
//Gestión del acelerado
}
void IVehiculo.Frenar(int n)
{
//Gestión del frenado
}
void IVehiculoGasolina.CambiarVelocidadInyeccion(int velocidad)
{
//Gestión de la inyeccion
}
void IVehiculo4x4.Activar4x4(bool activar)
{
//Gestión de 4x4
}
}
Estructuras de datos
Enumeraciones
La palabra clave enum se utiliza para declarar una enumeración, un tipo que
consiste en un conjunto de constantes con el nombre de lista de
enumeradores. Cada tipo de enumeración tiene un tipo subyacente, pudiendo
estos ser cualquier tipo integral menos char. El tipo predeterminado de los
elementos de la enumeración es int. Por defecto el primer enumerador tiene
el valor 0 y el valor sucesivo se incrementa en 1. Ejemplo:
int x = (int)Dias.Lunes;
Estructuras
Capítulo 11
1. C sharp NET / Capítulo 11
Capítulo 12
Manejo de excepciones
Todo esto gracias a las instrucciones 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
{
//haz esto...
//si i = 0 throw una excepción
}
catch
{
//si falló haz esto...
}
finally
{
//haya fallado o no, haz esto...
}
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 allá 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 vacío
if (s == null) //Si el string esta vacio
throw(new ExcepcionCadenaVacia()); //Lanzamos un error
personalizado
Console.WriteLine("Esto nunca se imprime"); //Si hay 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á
}
}
}
Capítulo 13
Delegación y Eventos
Hasta el momento hemos visto como hacer que un delegado guarde referencia
de un sólo método. Sin embargo, existe una clase, System.MulticastDelegate,
que deriva de System.Delegate, que se diferencia de esta última en que puede
tener múltiples métodos en su lista de invocaciones. Al usar la palabra clave
"delegate" se están usando estas clases de forma interna, sin tener que hacer
referencia a ellas en el código.
Para poder hacer esto usaremos los operadores sobrecargados '+=' y '-=' que,
respectivamente, añaden o eliminan a un método de la lista de invocaciones
de un delegado.
Para intentar asimilar esto mejor, veámoslo con un ejemplo más completo.
using System;
class Ejemplo {
class ClaseA {
class ClaseB {
public ClaseB () {
}
Podemos ver que, en este caso, nuestro delegado sólo manipula métodos que
no devuelvan nada y que reciban como único parámetro una cadena. Si
observamos los métodos que componen ClaseA y ClaseB, el denominado
MetodoNoValido no concuerda con la definición de nuestro delegado, ya
que recibe un entero y no una cadena. Eso implica que no vamos a poder
llamarlo desde ninguna instancia del delegado que hemos declarado. Sin
embargo, con las otras no tendremos ningún problema.
Como hemos dicho, hemos usado el operador '+=' para incluir otro método
más en nuestro delegado, en este caso MetodoPublico. Si usaramos de nuevo
el operador '=', borraríamos la antigua lista de invocaciones y crearíamos una
nueva con sólo una función referenciada. Ahora tenemos dos métodos en la
lista de invocaciones de nuestro delegado. Por último, creamos una instancia
de ClaseB, la cual en su constructor incluye una referencia más al delegado,
en este caso a MetodoPrivado.
Por último, una cuestión más. Hasta el momento hemos visto a delegados
que gestionan miembros que no devuelven ningún valor. Pero, ¿qué ocurre
cuando los devuelven? En este caso, la ejecución del delegado no devuelve
todos esos valores, sólo el que retorne el último método de su lista de
invocación.
Capítulo 14
C sharp NET/Capítulo 14
Capítulo 15
C sharp NET/Capítulo 15
Capítulo 16
C sharp NET/Capítulo 16
Capítulo 17
Capítulo 18
C sharp NET/Capítulo 18
Capítulo 19
XML
<?xml version="1.0"?>
<persona>
<nombre>Fabian</nombre>
<apellido>Seoane</apellido>
<organizacion>Mono Hispano</organizacion>
<pagina>http://fseoane.net</pagina>
</persona>
Si quieres saber más sobre XML te sugiero que mires las siguientes páginas:
http://w3.org/XML/, http://xml.com
XML en .Net
using System;
using System.Xml;
class EjemploXml{
writer.WriteEndElement();
writer.Flush();
writer.Close();
}
}
Capítulo 21
C sharp NET/Capítulo 21
Capítulo 22
Programando en Redes
Un ejemplo simple, puede ser un simple widget, que accede a un sitio web
para brindarnos la cotización de la moneda, la temperatura actual en nuestra
ciudad e incluso el pronóstico meteorológico para los proxmos días.
Capítulo 24
C sharp NET/Capítulo 24
Capítulo 25
C sharp NET/Capítulo 25
Capítulo 26
Por lo general tendremos que acceder a bases de datos tanto locales como
remotas, por eso .NET define distintos tipos que nos ayudan en esta tarea,
estos namespaces se conocen como ADO.NET que no es mas que una mejora
del tradicional ADO.
Finalmente nos queda por destacar que ADO.NET es una librería manejada
(managed library) lo que hace que su uso sea exactamente igual en cualquiera
de los lenguajes soportados por .NET.
Los tipos que componen ADO.NET tienen por objetivo obtener datos de la
base de datos rellenar un DataSet, manipular dicho elemento y devolver los
datos manipulados a la base de datos, con la particularidad de que dentro del
DataSet podemos tener la representación de tablas y relaciones entre ellas
hasta llegar a tener una representación completa de toda una base de datos.
Para poder trabajar correctamente con un DataSet están definidas dentro del
namespace System.Data algunas interfaces como son IDbCommand,
IDbDataAdapter, IDbConnection y IDataReader.
Hay dos proveedores que vienen con .Net predeterminados SQL que permite
acceder a SQL Server 7.0 o superior y OleDb que permite acceder a cualquier
base de datos que soporte OLE DB, también es común encontrarnos con
proveedores para bases de datos Oracle por ejemplo.
Capítulo 27
C sharp NET/Capítulo 27
Capítulo 28
Introducción
Limitaciones
Código de ejemplo
Este codigo puede usarse para probar una conexión via un MODEM serial
conectado al puerto /dev/ttyS0
using System;
using System.IO.Ports;
// Constructor
public SerialPortTest()
{
}
return rxString;
}
gmcs SerialExample.cs
mono SerialExample.exe
$ mono SerialExample.exe
Sportster 14,400/FAX RS Rev. 1.5
OK
ls -l /dev/ttyS0
El resultado del comando será una lista de los permisos sobre el puerto, por
ejemplo
$ ls -l /dev/ttyS0
crw-rw---- 1 root dialout 4, 64 2007-05-25 10:28 /dev/ttyS0
Links relacionados
Aquí hay unos links que podrían ser de utilidad. .NET Serial Port Library
(http://sourceforge.net/projects/serialportnet/) Este proyecto tiene como
objetivo implementar el namespace System.IO.Ports por completo para el
framework 1.1 de .NET.
Capítulo 29
Sockets
Sincrónico y Asincrónico
Clase Socket
using System.Net.Sockets;
Servidor
Cliente
0. PREAMBLE
We have designed this License in order to use it for manuals for free software,
because free software needs free documentation: a free program should come
with manuals providing the same freedoms that the software does. But this
License is not limited to software manuals; it can be used for any textual
work, regardless of subject matter or whether it is published as a printed
book. We recommend this License principally for works whose purpose is
instruction or reference.
This License applies to any manual or other work, in any medium, that
contains a notice placed by the copyright holder saying it can be distributed
under the terms of this License. Such a notice grants a world-wide, royalty-
free license, unlimited in duration, to use that work under the conditions
stated herein. The "Document", below, refers to any such manual or work.
Any member of the public is a licensee, and is addressed as "you". You accept
the license if you copy, modify or distribute the work in a way requiring
permission under copyright law.
The "Invariant Sections" are certain Secondary Sections whose titles are
designated, as being those of Invariant Sections, in the notice that says that
the Document is released under this License. If a section does not fit the
above definition of Secondary then it is not allowed to be designated as
Invariant. The Document may contain zero Invariant Sections. If the
Document does not identify any Invariant Sections then there are none.
The "Cover Texts" are certain short passages of text that are listed, as Front-
Cover Texts or Back-Cover Texts, in the notice that says that the Document
is released under this License. A Front-Cover Text may be at most 5 words,
and a Back-Cover Text may be at most 25 words.
The "Title Page" means, for a printed book, the title page itself, plus such
following pages as are needed to hold, legibly, the material this License
requires to appear in the title page. For works in formats which do not have
any title page as such, "Title Page" means the text near the most prominent
appearance of the work's title, preceding the beginning of the body of the
text.
The Document may include Warranty Disclaimers next to the notice which
states that this License applies to the Document. These Warranty
Disclaimers are considered to be included by reference in this License, but
only as regards disclaiming warranties: any other implication that these
Warranty Disclaimers may have is void and has no effect on the meaning of
this License.
2. VERBATIM COPYING
You may copy and distribute the Document in any medium, either
commercially or noncommercially, provided that this License, the copyright
notices, and the license notice saying this License applies to the Document
are reproduced in all copies, and that you add no other conditions whatsoever
to those of this License. You may not use technical measures to obstruct or
control the reading or further copying of the copies you make or distribute.
However, you may accept compensation in exchange for copies. If you
distribute a large enough number of copies you must also follow the
conditions in section 3.
You may also lend copies, under the same conditions stated above, and you
may publicly display copies.
3. COPYING IN QUANTITY
If you publish printed copies (or copies in media that commonly have printed
covers) of the Document, numbering more than 100, and the Document's
license notice requires Cover Texts, you must enclose the copies in covers
that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on
the front cover, and Back-Cover Texts on the back cover. Both covers must
also clearly and legibly identify you as the publisher of these copies.
The front cover must present the full title with all words of the title equally
prominent and visible. You may add other material on the covers in addition.
Copying with changes limited to the covers, as long as they preserve the title
of the Document and satisfy these conditions, can be treated as verbatim
copying in other respects.
If the required texts for either cover are too voluminous to fit legibly, you
should put the first ones listed (as many as fit reasonably) on the actual cover,
and continue the rest onto adjacent pages.
If you publish or distribute Opaque copies of the Document numbering more
than 100, you must either include a machine-readable Transparent copy
along with each Opaque copy, or state in or with each Opaque copy a
computer-network location from which the general network-using public has
access to download using public-standard network protocols a complete
Transparent copy of the Document, free of added material. If you use the
latter option, you must take reasonably prudent steps, when you begin
distribution of Opaque copies in quantity, to ensure that this Transparent
copy will remain thus accessible at the stated location until at least one year
after the last time you distribute an Opaque copy (directly or through your
agents or retailers) of that edition to the public.
It is requested, but not required, that you contact the authors of the
Document well before redistributing any large number of copies, to give them
a chance to provide you with an updated version of the Document.
4. MODIFICATIONS
You may copy and distribute a Modified Version of the Document under
the conditions of sections 2 and 3 above, provided that you release the
Modified Version under precisely this License, with the Modified Version
filling the role of the Document, thus licensing distribution and modification
of the Modified Version to whoever possesses a copy of it. In addition, you
must do these things in the Modified Version:
A. Use in the Title Page (and on the covers, if any) a title distinct from
that of the Document, and from those of previous versions (which
should, if there were any, be listed in the History section of the
Document). You may use the same title as a previous version if the
original publisher of that version gives permission.
B. List on the Title Page, as authors, one or more persons or entities
responsible for authorship of the modifications in the Modified
Version, together with at least five of the principal authors of the
Document (all of its principal authors, if it has fewer than five), unless
they release you from this requirement.
C. State on the Title page the name of the publisher of the Modified
Version, as the publisher.
G. Preserve in that license notice the full lists of Invariant Sections and
required Cover Texts given in the Document's license notice.
I. Preserve the section Entitled "History", Preserve its Title, and add
to it an item stating at least the title, year, new authors, and publisher
of the Modified Version as given on the Title Page. If there is no
section Entitled "History" in the Document, create one stating the
title, year, authors, and publisher of the Document as given on its Title
Page, then add an item describing the Modified Version as stated in
the previous sentence.
The author(s) and publisher(s) of the Document do not by this License give
permission to use their names for publicity for or to assert or imply
endorsement of any Modified Version.
5. COMBINING DOCUMENTS
You may combine the Document with other documents released under this
License, under the terms defined in section 4 above for modified versions,
provided that you include in the combination all of the Invariant Sections of
all of the original documents, unmodified, and list them all as Invariant
Sections of your combined work in its license notice, and that you preserve
all their Warranty Disclaimers.
The combined work need only contain one copy of this License, and multiple
identical Invariant Sections may be replaced with a single copy. If there are
multiple Invariant Sections with the same name but different contents, make
the title of each such section unique by adding at the end of it, in parentheses,
the name of the original author or publisher of that section if known, or else
a unique number. Make the same adjustment to the section titles in the list
of Invariant Sections in the license notice of the combined work.
6. COLLECTIONS OF DOCUMENTS
You may make a collection consisting of the Document and other documents
released under this License, and replace the individual copies of this License
in the various documents with a single copy that is included in the collection,
provided that you follow the rules of this License for verbatim copying of
each of the documents in all other respects.
You may extract a single document from such a collection, and distribute it
individually under this License, provided you insert a copy of this License
into the extracted document, and follow this License in all other respects
regarding verbatim copying of that document.
8. TRANSLATION
9. TERMINATION
You may not copy, modify, sublicense, or distribute the Document except as
expressly provided for under this License. Any other attempt to copy, modify,
sublicense or distribute the Document is void, and will automatically
terminate your rights under this License. However, parties who have received
copies, or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
The Free Software Foundation may publish new, revised versions of the
GNU Free Documentation License from time to time. Such new versions
will be similar in spirit to the present version, but may differ in detail to
address new problems or concerns. See http://www.gnu.org/copyleft/.