Documentos de Académico
Documentos de Profesional
Documentos de Cultura
C Sharp
C Sharp
mayo, 2005
Introducción a C#
Resumen
Este documento trata de mostrar de forma breve y sencilla una introducción al mundo
del C#, el lenguaje estrella de .NET que ha sido construido especialmente para
adaptarse de manera natural al framework y aprovechar al máximo todas sus
características. No trata de ser un manual de programación sino una pequeña
aproximación, los que quieran ir más allá pueden consultar las referencias de la
bibliografía.
Abstract
This document tries to show shortly an introduction to C#’s world, the new language of
.NET. C# has been built to fit .NET framework and use all its characteristics. It doesn’t
want to be a programming manual, but a little approximation. If anyone wants to know
more, he can consult references and bibliography.
i
Introducción a C#
Tabla de Contenidos
1. Introducción.............................................................................................. .Pág. 1
2. Características de C# ................................................................................ Pág. 2
3. Herramientas
- ii -
Gómez y Mohedano
Tabla de Figuras
iii
Introducción a C#
- iv -
1
1.- INTRODUCCIÓN
Durante dos décadas C y C++ han sido los reyes de los lenguajes de programación. Pero
apareció Internet y se produjo un cambio de necesidad del usuario respecto a la maquina.
Entonces nació Java que acabo convirtiéndose en el lenguaje de programación de Internet.
Basado en un código intermedio, producido mediante compilación, llamado Byte-code, que se
interpreta en cada ordenador mediante un interprete llamado maquina virtual, consiguiendo un
código independiente de la maquina, de la plataforma y gran robustez.
Aquí es donde entra en juego el señor Gates. Ante el imparable desarrollo en Java,
Microsoft aporta su producto de programación a la red, después de fracasar en el intento de su
propio Java (conocido como J++). Nace así la estrategia que Microsoft denomina .NET y su
gama de productos microsoft.NET.
Otra ventaja del uso de MSIL es que la cooperación entre C# y otros lenguajes .NET
ajustados a la CLS1 (Common Language Specification) es total, de tal forma que podemos
derivar una nueva clase C# tomando como base otra escrita en Visual Basic .NET, por poner un
ejemplo. Cada programador puede usar el lenguaje de su preferencia sin limitar las opciones de
los demás. Además C# nos deja interactuar con los componentes COM (ahora llamados COM+)
y programar a mas bajo nivel.
1
Para construir una máquina virtual común a todos los lenguajes primero hay que definir una serie de características
comunes a todos ellos. Este conjunto de características comunes se engloban en el llamado Common Languaje
Runtime(CLR)
Introducción a C#
2
1.- CARACTERÍSTICAS DE C#
⊗ Sencillez: C# elimina muchos elementos que otros lenguajes incluyen y que son
innecesarios en .NET. Por ejemplo:
⊗ Orientación a objetos: como hijo directo de C++, C# cuenta con la mayoría de las
características de orientación a objetos de aquél. La entidad de primer nivel es, como en
todos los lenguajes de esta categoría, la clase, definición a partir de la cual se crearían
objetos y derivarían nuevas clases. La encapsulación, la herencia y el polimorfismo son,
por tanto, los tres pilares básicos de la orientación a objetos en C# como en C++.
2
Esto significa que cuenta con construcciones sintácticas nativas para la definición, implementación y consumo de
propiedades, métodos y eventos, lo cual le diferencia claramente de C++ o Java.
-2-
Gómez y Mohedano
⊗ Seguridad de tipos: C# tiene mecanismos que aseguran que los accesos a tipos de
datos se realicen correctamente siempre. Esto los odiosos errores difíciles de detectar
por acceso a memoria no perteneciente a ningún objeto y es especialmente necesario en
un entorno gestionado por un recolector de basura. Para ello se toman las siguientes
medidas:
◘ Sólo se admiten conversiones entre tipos compatibles. Esto es, entre un tipo y
antecesores suyos, entre tipos para los que explícitamente se haya definido un
operador de conversión, y entre un tipo y un tipo hijo suyo del que un objeto del
primero almacenase una referencia del segundo (downcasting) Obviamente, lo
último sólo puede comprobarlo en tiempo de ejecución el CLR y no el
compilador, por lo que en realidad el CLR y el compilador colaboran para
asegurar la corrección de las conversiones.
◘ Se comprueba que todo acceso a los elementos de una tabla se realice con
índices que se encuentren dentro del rango de la misma.
-3-
Introducción a C#
⊗ Instrucciones seguras: Para evitar errores muy comunes, en C# se han impuesto una
serie de restricciones en el uso de las instrucciones de control más comunes. Por
ejemplo, no es posible utilizar un entero como único operando de una condicional,
evitando de esta manera que una asignación equivocada, por utilizar el operando = en
lugar del ==, genere un error lógico difícil de encontrar. Además todo caso de un switch
ha de terminar en un break o goto que indique cuál es la siguiente acción a realizar, lo
que evita la ejecución accidental de casos y facilita su reordenación.
⊗ Sistema de tipos unificado: A diferencia de C++, en C# todos los tipos de datos que se
definan siempre derivarán, aunque sea de manera implícita, de una clase base común
llamada System.Object, por lo que dispondrán de todos los miembros definidos en ésta
clase (es decir, serán “objetos”)
◘ El hecho de que todos los tipos del lenguaje deriven de una clase común facilita
enormemente el diseño de colecciones genéricas que puedan almacenar objetos
de cualquier tipo.
-4-
Gómez y Mohedano
3
1.- HERRAMIENTAS
• Entorno de IC#SharpCode:
Existe otro entorno de desarrollo open-source (GPL) del que podemos disponer del
código fuente. Está realizado en C# y nos permite la creación de proyectos, pero la última
versión (0.53) da bastantes problemas, así que habrá que esperar a que implementen una
versión más estable.
De todos modos, la herramienta tiene muy buen aspecto. Quien esté interesado puede
visitar su página: http://www.icsharpcode.net/
-5-
Introducción a C#
5
1.- PRIMER PROGRAMA EN C#: ¡Hello World!
Para iniciarse en C#, nada mejor que el típico programa de “¡Hello World!” que lo único que
hace al ejecutarse es mostrar por pantalla el mensaje ¡Hello World!.
El código necesario para ello, define una clase, llamada HelloWorld, que contiene un
método llamado Main(). En su interior introducimos la sentencia
System.Console.WriteLine(“¡Hello World!” ), de tal forma que el programa completo sería el
mostrado en programa1.
Using System;
class HelloWorld
{
static void Main()
{
System.Console.WriteLine(“¡Hello
World!” );
}
-6-
Gómez y Mohedano
6
1.- COMPILACIÓN
Una vez escrito el código anterior con algún editor de textos –como el Bloc de Notas de
Windows- y almacenado en formato de texto en un fichero HelloWorld.cs3, para compilarlo
basta abrir una ventana de consola (MS-DOS en Windows), colocarse en el directorio donde se
encuentre y pasárselo como parámetro al compilador así:
C:\ csc HelloWorld.cs
csc.exe es el compilador de C# incluido en el .NET Framework SDK para Windows de
Microsoft, y es posible llamarlo desde cualquier directorio en tanto que al instalarlo se añade
una referencia al mismo en el path. Si utiliza otros compiladores de C# puede que varíe la forma
en que se realice la compilación, por lo que lo que aquí se explica en principio sólo podría ser
válido para el compilador de Microsoft para Windows.
¡ Hello World !
Para compilar una aplicación en Visual Studio.NET primero hay que incluirla dentro de algún
proyecto. Para ello basta pulsar el botón Nuevo Proyecto en la página de inicio que se muestra
nada más arrancar dicha herramienta, tras lo que se obtendrá una pantalla con el aspecto
mostrado en la Ilustración 2.
3
El nombre que se dé al fichero puede ser cualquiera, aunque se recomienda darle la extensión .cs ya que es la
utilizada por convenio.
-7-
Introducción a C#
¡ Hello World !
-8-
Gómez y Mohedano
6
16- PLATAFORMA “MONO”
-9-
Introducción a C#
7
16- CLASES EN C#
4
También hay otras formas de definir las características de un tipo de objetos, como son las estructuras
y las enumeraciones.
- 10 -
Gómez y Mohedano
De este modo se definiría una clase de nombre < Clase_1 > cuyos miembros son los
definidos en < miembros > Los miembros de una clase son los datos y métodos de los que van a
disponer todos los objetos de dicha clase. Para declarar una clase sin ningún miembro,
utilizaríamos una sentencia como esta: class A { }
Una clase así declarada no dispondrá de ningún miembro excepto los implícitamente
definidos de manera común para todos los objetos que creemos en C#. Estos miembros se
definen dentro de la clase primitiva System.Object.
En C# existen muchos tipos de miembros. Entre ellos destacan:
class Persona
{
string Nombre;// Campo de cada objeto Persona que almacena su
nombre
int Edad; // Campo de cada objeto Persona que almacena
su edad
string NIF; // Campo de cada objeto Persona que almacena
su NIF
}
- 11 -
Introducción a C#
- 12 -
Gómez y Mohedano
8
16- CREACIÓN DE OBJETOS EN C#
El constructor toma como parámetros los valores con los que se desea inicializar el objeto a
crear. Gracias a él, se puede crear un objeto Persona de nombre José, de 22 años de edad y NIF
12344321-A , así: new Persona(“José”, 22, “12344321-A”)
Al igual que en C++, un objeto puede tener múltiples constructores, aunque para
diferenciar a unos de otros es obligatorio que se diferencien en el número u orden de los
parámetros que aceptan, ya que el nombre de todos ellos ha de coincidir con el nombre de la
clase de la que son miembros.
Una vez creado un objeto lo más normal es almacenar la dirección devuelta por new en una
variable del tipo apropiado para el objeto creado. El siguiente ejemplo muestra cómo crear una
variable de tipo Persona llamada p y cómo almacenar en ella la dirección del objeto que
devolvería la anterior sentencia usando el operador new:
La variable “p” contendrá una referencia a un objeto de clase Persona que representará a
una persona llamada José de 22 años y NIF 12344321-A.
- 13 -
Introducción a C#
El constructor por defecto es sólo incluido por el compilador si no hemos definido ningún
otro constructor. Si existe una clase en la que se haya definido algún constructor con parámetros
pero ninguno sin parámetros no será válido crear objetos de la misma llamando al constructor
sin parámetros, pues el compilador no lo habrá definido automáticamente. Por ejemplo, con la
última versión de la clase de ejemplo Persona no es correcto hacer:
Dentro del código de cualquier método de un objeto siempre es posible hacer referencia al
propio objeto usando la palabra reservada this. Así, los nombres de los campos podrán coincidir
con el de los parámetros. Por ejemplo en el código4, el constructor de la clase Persona escrito
anteriormente se puede rescribir así usando this.
El el código4 puede que no resulte muy interesante debido a que para evitar tener que
usar this podría haberse escrito el constructor tal y como se mostró en la primera versión del
mismo: dando nombres que empiecen en minúscula a los parámetros y nombres que empiecen
con mayúsculas a los campos.
Sin embargo, this es mas útil en C# a la hora de realizar llamadas a un método de un
objeto desde código ubicado en métodos del mismo objeto. En C# siempre es necesario que en
toda llamada a método de un objeto se utilice el operador ”.” <<Objeto.Metodo>>. Si el
método pertenece al mismo objeto que hace la llamada, la única forma de conseguir indicarlo
en C# es usando <<this. Metodo >>.
Finalmente, una tercera utilidad de this es permitir escribir métodos que puedan devolver
como objeto el propio objeto sobre el que el método es aplicado. Para ello se utilizaría una
sentencia la sentencia return this;
- 14 -
Gómez y Mohedano
9
1.- HERENCIA Y MÉTODOS VIRTUALES EN C#
A los miembros definidos en <miembrosHija> hay que sumarles los definidos en la clase
padre. Por ejemplo, a partir de la clase Persona puede crearse una clase Trabajador,como se
observa en el código5.
class Trabajador:Persona
{
public int Sueldo;
public Trabajador(string nombre, int edad, string nif, int sueldo)
: base(nombre, edad, nif)
{
Sueldo = sueldo;
}
}
Los objetos de esta clase Trabajador contarán con los mismos miembros que los objetos
Persona y además incorporarán un nuevo campo llamado Sueldo que almacenará el dinero que
cada trabajador gane. A la hora de escribir el constructor de esta clase ha sido necesario
escribirlo con una sintaxis especial consistente en preceder la llave de apertura del cuerpo del
método de una estructura de la forma: : base(<parametrosBase>)
A esta estructura se la conoce como inicializador base y se utiliza para indicar cómo se
desea inicializar los campos heredados de la clase padre. No es más que una llamada al
constructor de la misma con los parámetros adecuados, y si no se incluye, el compilador
consideraría por defecto que vale :base(), lo que sería incorrecto en este ejemplo debido a que
Persona carece de constructor sin parámetros.
- 15 -
Introducción a C#
class Persona
{
public string Nombre; // Campo de cada objeto Persona que almacena su nombre
public int Edad; // Campo de cada objeto Persona que almacena su edad
public string NIF; // Campo de cada objeto Persona que almacena su NIF
public Persona (string nombre, int edad, string nif) // Constructor de Persona
{
Nombre = nombre;
Edad = edad;
NIF = nif;
}
}
Trabajador(string nombre, int edad, string nif, int sueldo): base(nombre, edad, nif)
{ // Se inicializa cada Trabajador en base al constructor de Persona
Sueldo = sueldo;
}
Console.WriteLine ("Nombre="+p.Nombre);
Console.WriteLine ("Edad="+p.Edad);
Console.WriteLine ("NIF="+p.NIF);
Console.WriteLine ("Sueldo="+p.Sueldo);
}
}
- 16 -
Gómez y Mohedano
using System;
class Persona
{
public string Nombre; // Campo de cada objeto Persona que almacena su nombre
public int Edad; // Campo de cada objeto Persona que almacena su edad
public string NIF; // Campo de cada objeto Persona que almacena su NIF
public virtual void Cumpleaños() // Incrementa en uno de la edad del objeto Persona
{
Console.WriteLine(“Incrementada edad de persona”);
}
public Persona (string nombre, int edad, string nif) // Constructor de Persona
{
Nombre = nombre;
Edad = edad;
NIF = nif;
}
Trabajador(string nombre, int edad, string nif, int sueldo): base(nombre, edad, nif)
{ // Se inicializa cada Trabajador en base al constructor de Persona
Sueldo = sueldo;
}
t.Cumpleaños();
p.Cumpleaños();
}
}
- 17 -
Introducción a C#
También es importante señalar que para que la redefinición sea válida ha sido necesario
añadir la operador de control de acceso public en el método original, pues si no se incluyese se
consideraría que el método sólo es accesible desde dentro de la clase donde se ha definido, lo
que no tiene sentido en métodos virtuales ya que entonces nunca podría ser redefinido.
Las clases A y B del código6 son abstractas, y como puede verse es posible combinar en
cualquier orden el modificador abstract con modificadores de acceso.
La utilidad de las clases abstractas es que pueden contener métodos para los que no se dé
directamente una implementación sino que sean sus clases hijas quienes lo hagan. No es
obligatorio que las clases abstractas contengan métodos de este tipo, pero sí lo es marcar como
abstracta a toda la que tenga alguno. Estos métodos se definen precediendo su definición del
modificador abstract y sustituyendo su código por un punto y coma (;), como se muestra en el
método F() de la clase A del código 6.
Obviamente, como un método abstracto no tiene código no es posible llamarlo.
Todo método definido como abstracto es implícitamente virtual, pues si no sería imposible
redefinirlo para darle una implementación en las clases hijas de la clase abstracta donde esté
definido. Por ello es necesario incluir el modificador override a la hora de darle
implementación. No es posible marcar un objeto como abstract y virtual a la vez, ya que
produce un error de compilación.
En cambio, sí es posible marcar un método como abstract y override a la vez, lo que
convertiría al método en abstracto para sus clases hijas y forzaría a que éstas lo tuviesen que
reimplementar si no se quisiese que fuesen clases abstractas.
- 18 -
Gómez y Mohedano
10
1.- POLIMORFISMO EN C#
using System;
class Persona
{
public string Nombre; // Campo de cada objeto Persona que almacena su nombre
public int Edad; // Campo de cada objeto Persona que almacena su edad
public string NIF; // Campo de cada objeto Persona que almacena su NIF
public virtual void Cumpleaños() // Incrementa en uno la edad del objeto Persona
{
Console.WriteLine(“Incrementada edad de persona”);
}
public Persona (string nombre, int edad, string nif) // Constructor de Persona
{
Nombre = nombre;
Edad = edad;
NIF = nif;
}
Trabajador(string nombre, int edad, string nif, int sueldo): base(nombre, edad, nif)
{ // Inicializamos cada Trabajador en base al constructor de Persona
Sueldo = sueldo;
}
p.Cumpleaños();
// p.Sueldo++; //ERROR: Sueldo no es miembro de Persona
}
}
- 19 -
Introducción a C#
El mensaje mostrado por pantalla al ejecutar este método confirma lo antes dicho respecto
a que la versión de Cumpleaños() a la que
Incrementada edad de trabajador
se llama, como se puede comprobar en la
ilustración 3.
- 20 -
Gómez y Mohedano
11
1.- CONCLUSIÓN Y BIBLIOGRAFÍA
Conclusión
C# es un lenguaje de programación moderno e innovador que incorpora cuidadosamente
características encontradas en los lenguajes industriales y de investigación más habituales.
Manteniendo la filosofía de diseño de C#, Microsoft ha introducido varias características nuevas
potenciales al lenguaje C# con el fin de aumentar la productividad del desarrollador con
construcciones de lenguaje.
Información de referencia
⊗ Manuales de C#
- 21 -