Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Introducción.
C# es un lenguaje orientado a objetos (es más correcto decir orientado a componentes)
diseñado para el CLR (Common Language Runtime) de la plataforma .NET que se
llamó en un principio NGWS, es decir, Next Generation Windows Services.
Visual Studio.NET soporta esta plataforma y también el lenguaje C#, así como C++,
Visual Basic y los lenguajes de script VBScript y JScript.
Por ejemplo: se eliminan los punteros (es posible utilizarlos en un código llamado
inseguro), las macros, las plantillas, la herencia múltiple, los ficheros de cabecera, IDL,
librerías de tipos... Además se añaden otras características, como orientación a objetos
casi pura, seguridad de tipos, versiones, gestión automática de memoria (garbage
collector)...
1/13 1
Marco Besteiro y Miguel Rodríguez Introducción al lenguaje C#
los punteros a funciones, con la ventaja de ser más seguro y respetar los tipos de
datos.
- Se cambian ciertos aspectos referentes a los operadores:
o No se utilizan los operadores -> ni ::. El único operador de acceso a
métodos de objetos que se utiliza es el operador punto ‘.’ .
o Se incluyen dos operadores nuevos: is y typeof.
o Se cambia el funcionamiento de los operadores lógicos &, ^ y |.
o La sobrecarga de operadores es diferente.
- Hay ciertas palabras clave que se utilizan de modo distinto, como extern y
static.
- El método Main se declara de modo distinto.
- No se permiten las declaraciones adelantadas (forward).
- El manejo de errores se hace mediante excepciones.
- No se soportan las macros, aunque sí las directivas de preprocesador.
- No se utilizan ficheros de cabecera (.h) ni similares (IDL y librerías de tipos). El
código es compilado en unidades llamadas assemblies, en las cuales se almacena
la representación del código en un lenguaje intermedio llamado IL y los
metadatos, que sustituyen a los ficheros .h de C++ (o a las librerías de tipos y
entradas de registro). Los assemblies se pueden generar a partir de código escrito
en otros lenguajes, como C++ o Visual Basic, lo cual quiere decir que desde C#
se puede utilizar código IL generado a partir de otros lenguajes.
- Los assemblies se agrupan en namespaces (que siguen una estructura
jerárquica).
- No existe una librería de tiempo de ejecución (Runtime) C# como en C y C++.
En su lugar existe un Runtime .NET accesible a través de la clase System.
- El mecanismo de herencia sufre cambios:
o No se permite herencia múltiple en clases pero sí en interfaces.
o La sobrescritura de métodos se ha de hacer utilizando el operador
explícito override.
o El modificador new permite ocultar miembros heredados.
- Existen tres posibles grupos de tipos:
o Tipos valor: son tipos primitivos como char, int, struct... C# incluye
dos tipos nuevos, boolean (True o False, se utiliza en las sentencias
condicionales, en lugar de integer, como se hacía en C++) y decimal
(para operaciones financieras). Las variables de tipo valor se guardan en
la pila.
o Tipos referencia: incluye los tipos class, interface, delegate y
array. Los objetos referenciados por variables de tipo referencia se
guardan en el heap o montón. Existen dos tipos de referencia
predefinidos, object y string. object es el tipo base de la jerarquía de
clases .NET. Todo dato deriva del tipo object mediante herencia simple
(sólo se permite herencia múltiple de interfaces). Todo dato de cualquier
otro tipo puede convertirse a object (a esta conversión se la llama
boxing) permitiéndose también la operación inversa (unboxing). Esto
permite la existencia de lo que se denomina sistema de tipos unificado.
o Tipos puntero: sólo se permite su utilización en código inseguro.
- Las sentencias sufren ciertos cambios y aparecen otras nuevas:
o La sentencia switch admite string.
o La sentencia foreach se puede aplicar a tipos y colecciones.
2/13 2
Marco Besteiro y Miguel Rodríguez Introducción al lenguaje C#
Por último, C# permite la interoperación con otros lenguajes en base a las siguientes
características:
- Acceso a librerías a través de COM+ y los servicios .NET.
- Soporte XML para interacción basada en componentes.
- Simplificación de la administración y desarrollo de aplicaciones y componentes
gracias a un cuidado mecanismo de versiones.
3/13 3
Marco Besteiro y Miguel Rodríguez Introducción al lenguaje C#
La plataforma .NET
Podría pensarse en la plataforma .NET como un sustituto de la arquitectura Windows
DNA (Distributed Network Architecture) pero sería una comparación insuficiente. La
arquitectura DNA se centra en la construcción de aplicaciones de tres capas para
Windows basándose en tecnologías como ASP, COM, etc...
El CLR ofrece las bases para poder ejecutar los servicios. Las clases base ofrecen el
control de tipos de datos básico, las clases de tipo colección y de otras clases generales.
Los servicios de datos permiten el acceso a los datos desde los servicios Web y
Windows, para lo cual tienen clases de soporte de datos y XML.
4/13 4
Marco Besteiro y Miguel Rodríguez Introducción al lenguaje C#
La ventaja que implica soportar un lenguaje intermedio es que las aplicaciones que se
ejecutan sobre el CLR son portables. Al no depender de una máquina concreta, sólo
necesitan para ejecutarse sobre cualquier máquina que el CLR esté instalado en tal
máquina.
Como todo entorno de ejecución, el CLR se ayuda de una librería de clases para ofrecer
una serie de servicios a los desarrolladores, permitiendo que puedan desarrollar
aplicaciones sencilla y rápidamente reutilizando componentes así como que puedan
desarrollar componentes reutilizables.
5/13 5
Marco Besteiro y Miguel Rodríguez Introducción al lenguaje C#
Metadatos.
Para permitir al CLR ofrecer servicios al “managed code” los compiladores no sólo han
de generar el código IL correspondiente al código fuente, sino también metadatos, los
cuales se almacenarán junto con el código intermedio IL y harán innecesario el registro
del sistema (los metadatos son a la plataforma .NET lo que las bibliotecas de tipos, las
entradas del registro del sistema y algún que otro dato son a COM). Para un objeto de la
plataforma .NET, los metadatos guardan información necesaria para utilizar el objeto,
como puede ser:
6/13 6
Marco Besteiro y Miguel Rodríguez Introducción al lenguaje C#
El CLR utilizará los metadatos para localizar y cargar clases, resolver invocaciones a
métodos, generar código nativo, gestionar la seguridad, manejar las instancias de clases
y fijar los límites del contexto de tiempo de ejecución.
Assemblies.
El CLR trabaja realmente con assemblies. Un assembly es un fichero con un formato
muy parecido al formato PE (el que se utiliza en los ficheros .exe o .dll tradicionales)
que contiene el código IL resultado de compilar el código fuente, los metadatos y otros
ficheros necesarios para poder ejecutar el paquete o assembly. Además, un assembly
contiene un fichero llamado “fichero de manifiesto” o manifest, el cual indica los
assemblies de los que depende, los ficheros que contiene, controla los tipos y recursos
expuestos por el assembly y establece un mapeo entre esos tipos y recursos y los
ficheros que contienen esos tipos y recursos.
El CLR provee APIs que los motores de scripts pueden utilizar para crear
dinámicamente un assembly a partir de un script. A este tipo de assemblies se les llama
assemblies dinámicos y podría ser considerado como un tercer tipo.
7/13 7
Marco Besteiro y Miguel Rodríguez Introducción al lenguaje C#
Como puede verse, el fichero de manifiesto (manifest) puede ser almacenado de varios
modos:
- Para un assembly de un fichero, el manifiesto es incorporado al fichero PE.
- Para un assembly de varios ficheros, el manifiesto puede almacenarse como un
fichero separado o puede incorporarse en uno de los ficheros PE del assembly.
El assembly que contiene los tipos básicos del CLR se llama mscorlib.dll y es el
único que se toma por defecto al compilar. Si se desea utilizar un tipo que esté en otro
assembly, ha de indicarse al compilador el nombre de tal assembly.
Namespaces.
Así como un assembly es una agrupación física de clases, otros tipos e información
sobre tales, un namespace es una agrupación lógica. De este modo, al escribir el código
de una aplicación y utilizar clases y otros tipos se ha de indicar (en el código) el
namespace al que pertenecen tales tipos, no el assembly. Como se ha comentado, el
assembly se ha de pasar como parámetro al compilador.
La lógica que lleva a esta separación es muy sencilla. Supóngase que se crean 5
assemblies con tipos relacionados con el manejo de redes. Aunque físicamente son 5
ficheros distintos, lógicamente se refieren al mismo tema, de modo que podrían estar
agrupados bajo un mismo nombre lógico (nótese que namespace significa “espacio de
nombre”).
De modo similar, un assembly puede contener clases y tipos dispares que puedan ser
divididos en varios namespace. De hecho, tal es el caso del assembly mscorlib.dll en
el que uno de sus namespace es System. El namespace System incluye los tipos de bajo
nivel básicos, como el tipo base Object, Byte, Int32, Math y Delegate.
8/13 8
Marco Besteiro y Miguel Rodríguez Introducción al lenguaje C#
Los namespace forman una jerarquía lógica, lo cual quiere decir que se pueden anidar.
Por ejemplo, dentro del namespace System se encuentra el namespace Collections
que incluye tipos como ArrayList, BitArray, Queue y Stack.
Se podría pensar, recordando que un assembly puede ser partido en varios ficheros, que
el assembly puede también realizar la función del ejemplo comentado. Visto así es
cierto, pero el hecho de partir un assembly en varios ficheros se realiza por motivos de
eficiencia en la transmisión de sólo parte del assembly, no por motivos de organización
lógica.
Attributes.
Para poder convertir una clase en un componente es necesaria información adicional
sobre la clase como:
Los atributos no son valores concretos y son extensibles, lo cual puede hacerlo el propio
programador.
9/13 9
Marco Besteiro y Miguel Rodríguez Introducción al lenguaje C#
Esta conversión se realiza una sola vez, si se vuelve a invocar durante la ejecución un
código ya compilado a código nativo, se utiliza el código nativo.
Por defecto no se elige la opción de compilar todo el assembly a nativo, ya que implica
un coste de tiempo que en la mayoría de los casos no se ve justificado, ya que es raro
que se ejecute todo el código del assembly en una ejecución concreta.
Según lo comentado, la ejecución del código intermedio de un assembly por parte del
CLR es algo así:
Por ejemplo: el CTS permite a un tipo clase contener cero o más miembros, los cuales
pueden ser campos, métodos, propiedades o eventos.
10/13 10
Marco Besteiro y Miguel Rodríguez Introducción al lenguaje C#
Al intentar llevar a cabo esta interoperabilidad entre lenguajes el primer problema que
aparece son las diferencias que hay entre los diversos lenguajes. Para salvar este
11/13 11
Marco Besteiro y Miguel Rodríguez Introducción al lenguaje C#
problema a la hora de crear tipos .NET que sean fácilmente accesibles desde otros
lenguajes de programación es necesario utilizar características de cada lenguaje que
sean compatibles con los demás. Para hacer esta labor más sencilla, Microsoft ha
definido el CLS, que informa a los proveedores de compiladores del conjunto mínimo
de características que han de soportar sus compiladores para adaptarse al CLR.
Se dice que un tipo es compatible con el CLS si todas sus partes accesibles
públicamente:
- Están compuestas sólo por tipos compatibles con el CLS.
- En caso de que alguna no esté compuesta por tipos compatibles con el CLS ha
de estar marcada explícitamente como no compatible con el CLS.
Se dice que una herramienta es un consumidor compatible con el CLS si puede utilizar
íntegramente cualquier tipo compatible con el CLS, es decir, llamar a cualquier método
compatible con el CLS, crear una instancia de cualquier tipo compatible con el CLS,
leer y modificar cualquier campo compatible con el CLS, etc...
Por último, se dice que una herramienta es un extensor compatible con el CLS si es un
consumidor compatible con el CLS y además puede extender cualquier clase base
compatible con el CLS, implementar cualquier interface compatible con el CLS, definir
nuevos interfaces compatibles con el CLS y situar cualquier atributo compatible con el
CLS en todos los elementos de metadatos apropiados.
El VES ofrece los servicios necesarios para ejecutar “managed code” y “managed data”,
así como utilizar los metadatos para conectar en tiempo de ejecución (“enlace tardío” o
“late binding”) módulos que han sido generados por separado.
Verificación y Seguridad.
La seguridad es inherente al diseño de la plataforma .NET. Entra en acción tan pronto
como una clase es cargada realizando chequeos para verificar el código (seguridad de
tipos...).
Tras los chequeos controla el acceso del código a los recursos. La seguridad de la
plataforma .NET ofrece mecanismos para controlar la identidad y las posibilidades del
código. Estos mecanismos alcanzan los límites del contexto, del proceso y de la
máquina para asegurar la seguridad de los datos en escenarios remotos. Estos
mecanismos de seguridad trabajan y extienden los mecanismos de seguridad del
Sistema Operativo.
12/13 12
Marco Besteiro y Miguel Rodríguez Introducción al lenguaje C#
13/13 13