¿Qué es .NET?
.NET es una nueva arquitectura, desarrollada por
Microsoft, que permite el desarrollo de aplicaciones y su correcta ejecución,
con una orientación totalmente guiada hacia el objeto e Internet.
¿Por qué?
Viendo las carencias reales de los entornos de
programación actuales se decide desarrollar un entorno para solventar la gran
cantidad de problemas que se daban en ese momento:
Ø Inconsistencias de Windows
·
La
aparición de 3 tipos totalmente diferentes de programación de gráficos (GDI, DirectX, OpenGL)
·
Diferentes
modelos de programación para acceder a bases de datos (DAO, RDO, ADO) siendo todas incompatibles unas con otras.
·
Diferentes
versiones de la misma plataforma, Windows 95, 98, Me, NT, 2000, CE, XP. Además
también tenemos para cada versión diferentes variantes, Profesional, Server, …
·
A
nivel de seguridad también nos encontrábamos con muchas diferencias desde su
carencia en Windows 95 hasta la seguridad de Windows NT o el Windows 2000
Server.
Ø Defectos COM
·
Todos
los objetos COM dependen del registro del sistema, el cual se suele alterar con
facilidad.
·
Las
versiones de los COM tienden a dar problemas cuando al tener actualizadas las
librerías se intenta usar una versión antigua.
·
Su
instalación no es nada sencilla.
§
Copiar
todos las librerías que usa en el PC
§
Registrar
todas esas librerías en el Registro de Windows., teniendo en cuenta no
sobrescribir versiones antiguas.
§
Configurarlas.
§
…
Ø Problemas con la orientación a objeto
·
El
modelo COM no permite heredar ni extender sus clases
·
Las
APIs de Windows tampoco exponen sus clases.
·
Los
objetos COM tienen un problema de referencias circulares. Si dos objetos
poseen una propiedad en la cual cada uno referencia al otro esos dos objetos no
son liberados de la memoria automáticamente.
Ø Interoperatibilidad entre
lenguajes
·
La
plataforma Windows dificulta en gran medida la integración de piezas escritas
en diferentes lenguajes de programación.
§
Desde
Visual Basic se pueden hacer llamadas a DLL escritas en C++ pero hay que tener
en cuenta los enteros con signo(no
reconocidos por vb)
§
Si
programamos en VBScript, podemos usar objetos COM pero no podremos sacarle
partido a ninguna interface.
§
Cada
lenguaje tiene una forma propia de control de errores.
Ø Problemas con ASP
·
Solo
se pueden usar lenguajes tipo script (VBScript,
JScript)
·
El
código esta mezclado con la GUI, (HTML),
lo que dificulta muchísimo separar la lógica de programación.
·
No
se pueden añadir objetos COM sin reiniciar el IIS, y nos obliga a que estés COM estén registrados en el
registro de Windows
·
La
reutilización del código es complicada
·
Las
sesiones no son del todo efectivas. (Desactivar
cookies, granjas web)
Ø Desafíos de Internet
·
Un
gran problema es la posibilidad de compartir datos desde un sitio web a otro.
Me refiero a poder sacar información de una web que se nos muestra y extraer
esa información para un uso en otra aplicación.
A causa de todos estos problemas y
muchos otros, pues Microsoft se decide a sacar una plataforma que, en gran
medida, solucione la mayoría de problemas con los que se encontraban los
programadores.
Soluciones que
ofrece .NET Framework
Ø Los componentes .NET procuran
suplantar los objetos COM
Ø En la plataforma .NET no se usa el
registro para almacenar las diferentes versiones de cada componente.
·
Los
componentes privados se almacenan con la aplicación que los usa
·
El
resto de los componentes se almacenan en el llamado GAC, cache de ensamblados general. (C:\WinNT\Assembly)
·
El
control de versiones esta muy mejorado con respecto a los objetos COM:
§
Cada
versión del mismo componente se almacena en el PC, por tanto cuando una
aplicación llame a una versión anterior la encontrara sin problemas de
conflictos de versiones.
§
Las
llamadas a las diferentes versiones pueden ser configuradas mediante archivos
de configuración, por lo que se podría mejorar uno de los componentes y luego
direccional las llamadas a la nueva librería sin ningún tipo de dificultad.
Ø Toda la jerarquía de diseño de
.NET esta orientada totalmente al objeto. Todos los objetos derivan de
System.Object.
Ø El problema de las referencias
circulares deja de serlo con este tipo de arquitectura.
Ø TODOS los lenguajes .NET funcionan
a partir de la misma raíz, la clase System.Object. Esto potencia que todos los
lenguajes .NET tendrán que llamar a las mismas librerías para hacer la misma
función.
Ø Los programas desarrollados en un
lenguaje de la arquitectura .NET funcionaran en cualquier plataforma que tenga
implantada el Framework .NET. Por tanto la portabilidad de los programas deja
de ser un problema Ahora mismo un programa escrito en C# podría funcionar
perfectamente en un sistema linux, por ejemplo.
Arquitectura del
.NET Framework
En la parte inferior se encuentra Windows API.
.NET proporciona una interface para
trabajar con las llamadas a las API pero no las sustituye.
Luego tenemos los servicios COM+. Microsoft no
comenzó a desarrollar la arquitectura desde 0, si no partiendo de la base de
los servicios COM+. Por tanto desde la plataforma .NET podemos hacer llamadas a
los objetos COM.
Jscript …
Visual Basic C# C++ Especificación
del lenguaje común (CLS) ASP.NET Windows Forms Datos y XML Biblioteca de
clase base Runtime del
lenguaje común
Windows API Servicios COM+
El runtime del lenguaje común es la primera capa
que pertenece a .NET Framework.
Esta capa se encarga de los servicios básicos de .NET:
·
Administración
de memoria
·
Recolección
de objetos no utilizados
·
Control
de excepciones
MSCorEE.DLL es la librería principal del runtime y se lanza cuando se
ejecuta una aplicación en .NET.
La biblioteca de clase base (BLC) es la jerarquía de objetos, tipos numéricos,… Es común para
todos los lenguajes.
La capa de datos y XML contiene las clases de acceso a datos y con XML.
Hay clases específicas para leer y escribir archivos XML con suma facilidad. La
parte de datos de esta capa se llama ADO.NET
y es el equivalente a la tecnología ADO, aunque centrada principalmente
en los resultados desconectados, denominados DataSets)
Esta capa define el entorno del usuario. Están al mismo
nivel puesto que ambos son parte de un entorno grafico.
La especificación de lenguaje común (CLS) es un conjunto de especificaciones
para ayudar a la creación de nuevos compiladores. Son las características que
debe seguir un compilador, como compatibilidad con enteros con signo de 16, 32
y 64 bits, matrices con índice inferior a 0 y control estructurado de
excepciones.
En la parte superior del diagrama tenemos los lenguajes de
programación compatibles con CLS.
Todos los lenguajes .NET producen código administrado, que
es el código que se ejecuta bajo el control del runtime.
Este código es muy distinto del código nativo producido
por los compiladores tradicionales, puesto que no es un código directamente
entendible por la maquina si no que pasa por un interprete que lo convierte.
PRIMER PROGRAMA CON
VISUAL BASIC .NET
Module Module1 Sub
Main () Dim
x as Double, res as Double x = 12.5 res = Sumar(x, 46.6) System.Console.Write(“El resultado es ”) System.Console.WriteLine(res) End Sub Function
Sumar(ByVal n1 as
Double, ByVal
n2 as Double)
As Double Add = n1 + n2 End Function End
Module
Guardaremos este programa como prueba1.vb
Para compilar este programa usaremos el compilador que nos
instala el Framework.
Se encuentra en C:\DirWindows\Microsoft.NET\Framework\vx.y.zzzz
El compilador se llama vbc.
Para compilarlo pondremos lo siguiente: C:\WINNT\Microsoft.NET\Framework\v…\vbc
prueba1.vb
Como podemos comprobar es un programa muy simple, y aunque
la estructura de los comandos es diferente de la del Visual Basic 6, es
sencillo saber que hace.
Esta operación nos generara un archivo llamado prueba1.exe.
Al ejecutarlo tendremos la siguiente salida: El
resultado es 59
Lenguaje Intermedio
de Microsoft (MSIL)
Como habíamos comentado antes, el .NET no genera código
nativo, o sea, código entendible por el ordenador; el código que genera es
llamado MSIL o IL, es un lenguaje intermedio entre en lenguaje
maquina y un procesador virtual.
Para ver este tipo de código vamos desensamblar el
ejecutable que creamos en el ejemplo anterior.
Para tal tarea el Framework .NET tiene una utilidad llama
ILDASM (Desensamblador IL), para usarlo pondríamos lo siguiente:
ildasm
prueba1.exe /Out=prueba.il
Como podéis comprobar, esto nos genera un archivo llamado
prueba.il, que al abrirlo con el Block
de Notas comprobamos el código en IL del ejecutable que hemos creado desde
VB.NET.
Aunque no vamos a comentar todas las líneas que tenéis en
ese archivo si vamos a hablar de alguna de ellas:
·
Las
instrucciones .assembly son llamadas a
las DLL externas
·
La
instrucción .method public static void Main() cil
manager marca el principio del código IL producido por el
procedimiento Sub Main() del código original en VB.
Aparte de un desensamblador, el Framework también nos
permite volver a ensamblar un archivo en IL en un nuevo exe, para ello usaremos
la utilidad ILASM.
Antes vamos a hacer los siguientes cambios en el archivo
que tenemos abierto en este momento:
·
Buscaremos
la línea donde pone “El resultado es “
·
La
cambiaremos por “12.5 + 46.5 = “
·
Lo
guardaremos como pruebaIL.il
Ahora pondremos la siguiente línea:
ilasm
pruebaIL.il.
Como podéis observar esto nos genera un nuevo archivo ejecutable
el cual podemos ejecutar y observar el cambio que hemos realizado.
El Compilador Just-In-Time (JIT)
Actualmente no existe ninguna CPU capaz de ejecutar código
en IL.
Entonces, como se pueden ejecutar las aplicaciones que
programamos en .NET, pues bien la respuesta es por medio del JIT.
Ahora veremos los pasos que suceden al ejecutar una
aplicación en IL:
1. Lo primero que hacen todos los
ejecutables en .NET es cargar la librería MSCorEE.DLL que es el runtime
de .NET y a continuación llamas a la función _CorMainExe.
2. La función _CorMainExe
busca en el ejecutaba el punto de partida de la aplicación (El procedimiento
Sub Main, normalmente)
3. EL código en IL es entregado al
JIT que lo convierte en código nativo y lo ejecuta.
4. A medida que se llamen a otros
métodos, el runtime utiliza el JIT para convertir ese código de IL a código
nativo. Esto solo pasa la primera vez por cada función cada vez que ejecutamos
la aplicación.
Que supone esto… la aplicación tarda un poco mas de lo
normal en iniciarse, aunque suele ser un par de segundos, aunque por otro lado
siempre tendremos un ejecutable adaptado perfectamente a las características de
la CPU donde se ejecuta el archivo.
El JIT no es un compilador tradicional, esta muy
optimizado para sacar el máximo partido a la CPU donde se ejecuta pudiendo
ganar con esto mucha optimización de código.
Aun así, el Framework incluye una aplicación para generar ejecutables en código nativo,
aunque esta técnica gane tiempo al inicio del programa hace perder la
optimización que puede realizar el JIT para cada CPU en concreto.
Ensamblados
El Framework .NET permite la creación de varios tipos de
aplicaciones:
·
Aplicaciones
de consola de Windows
·
Formularios
de Windows
·
Servicios
de Windows
·
Componentes
·
Formularios
Web
·
Servicios
Web XML
Nosotros, independientemente del la aplicaciones que
estemos desarrollando podemos insertar varios tipos de archivos en un mismo
ensamblado, llamado anteriormente ejecutable.
En nuestro ensamblado podemos meter los ejecutables de las
aplicaciones, las fotos que usemos, paginas web, ….
Después de toda esta teoría, que es necesaria para una
programación efectiva en .NET Framework, pasaremos a algo mucho más ameno.
Antes de empezar hay que aclarar que ya no hay diferencias entre módulos y archivos de formularios, todos los archivos tienen la misma extensión en Visual Basic .NET puesto que dentro del mismo archivo podemos tener formularios, clases, y módulos. Nunca hay que olvidar que los formularios no son mas que una clase que hereda de System.Windows.Forms.Form y no hay diferencia entre una clase nuestra y un formulario, en lo que concierte al la forma de manejarlo.
Módulos:
Los módulos son bloques
delimitados por las palabras clave Module y End Module y pueden contener cualquier numero de variables, Subs y Functions.
Un ejemplo de esto es nuestra
aplicación prueba1, en ella teníamos un modulo llamado Module1 y dentro
del mismo teníamos un Sub y un Function.
Sub New:
Los módulos como se puede ver
son similares a los disponibles en las versiones anteriores.
Sin embargo ahora disponen de
funciones adicionales tales como el método New.
Si un modulo contiene un método New, la
rutina se llamara antes de ejecutar el código contenido en el mismo modulo.
Esto es muy importante y debe
ser tenido en cuenta por que las clases funcionan de una manera similar puesto
que contienen un método New que funciona de la misma forma que en los módulos.
Hay que recordar que este método
solo se llamara cuando se haga referencia a una función o una variable del
modulo no cuando se haga referencia a una constante.
Sub Main:
Como sucede en las versiones anteriores se puede
decidir si la aplicación se iniciara con una clase visible como un formulario o
con un procedimiento Sub Main definido en un
módulo.
El problema de versiones
anteriores por tener varios métodos Sub Main en
módulos diferentes ya esta resuelto puesto que se puede indicar que método
exactamente es el que se desea iniciar. Para ello debemos ir a la ventana de
Paginas de propiedades del proyecto.
Clases:
Las clases se definen por el
modulo contenido entre Class y End Class.
Una clase puede contener tanto
variables publicas como privadas y se pueden definir propiedades que tienen
características diferentes a las variables comunes.
Espacios de Nombre:
Tanto los módulos como las
clases habitan en espacios de nombre. Las miles del clases del Framework se contienen en espacios de nombre, por
ejemplo dentro del espacio de nombres System
tenemos las clases de tipos básicos como Integer,
String, ...
Dentro de un mismo proyecto
podemos definir varios espacios de nombre lo que nos permite una estructuración
muy completa y ordenada del mismo.
Otra característica importante
es que los espacios de nombre se pueden anidar y así obtener una buena
ordenación de la aplicación.
Imports:
La instrucción imports permite acceder a partes de un espacio de nombres sin obligar a incluir su ruta completa.
Por ejemplo, si nosotros tenemos
que usar mucho la clase Form que reside dentro
del espacio de nombre System.Windows.Forms pues
en vez de escribir la ruta completa cada vez que deseemos crear una instancia
de esa clase podemos introducir una instrucción imports y así omitirla.
Imports
System.Windows.Forms
Con esa línea podríamos crear
una instancia de Form solo con introducir Form.
En este apartado veremos como
definir las variables para poder almacenar todo tipo de datos en nuestra
aplicación.
Declaraciones:
Las declaraciones son similares
a las versiones anteriores.
Para declarar una variable se
una Dim, Private, Public o Static. Las reglas de ámbito son similares a las de
visual basic 6.
Ø
Deberá utilizar Dim dentro de un procedimiento para declarar una variable local que solo
será visible dentro de dicho procedimiento.
Ø
Deberá utilizar Dim o Private fuera de los bloques
de procedimiento para crear variables a las que poder acceder dentro del modulo
o clase pero no desde otra parte fuera de ese ámbito.
Ø
Podrá utilizar Public desde un modulo para crear
variables globales.
Ø
Podrá utilizar Public desde una clase para crear un
campo publico accesible desde fuera de la clase.
Ø
Podrá utilizar Static para crear variables
estáticas que no cambien su valor en cada llamada a dicha variable.
Mediante Option Explicit podemos controlar si deseamos que el editor nos
indique si una variable no esta definida indicando On/Off después de la
declaración de la instrucción.
Option Explicit
On ‘Activaría el control de variables sin definir
Option Explicit
Off ‘Desactivaría
dicho control
Ahora podemos hacer declaraciones múltiples sin que el la ultima variable sea la que realmente tome el tipo de dato indicado.
Dim a, b, c As
Integer
Esto nos crearía tres variables
de tipo Integer y no c de tipo Integer y, a y b de tipo Variant
como sucedía en versiones anteriores.
Otra cosa añadida en Visual Basic .NET son las variables de ámbito. Si
definimos una variable dentro de un bucle, dicha variable solo pertenece a ese
bucle y no es accesible desde fuera. Al salir del bucle todas las variables
definidas en su interior se eliminan de memoria.
Ejemplo de variable de ambito:
For i = 1 to 10
...
for j = 1 to 10
‘ Esto hace que por cada ciclo
de j , x tenga un valor de 0.
Dim x as Int16 = 0
...
Tipos de datos:
§
Object: En primer lugar el tipo
de datos Variant ya no existe. Cualquier tipo de dato puede ser almacenado en
una variable tipo Object puesto que todas las clases de .NET heredan de esta
clase base.
§
Enteros: Este
es un tipo de datos numérico. En Visual Basic .NET tenemos 3 variantes.
·
Long: 64 bits int64
·
Integer: 32
bits int32
·
Short: 16 bits int16
§
Boolean: Valor
que puede almacenar 2 valores. Ocupa 4 bytes a diferencia de Visual Basic 6
donde ocupaba 2 bytes. Otra diferencia es que el valor True
se almacena como –1 en vez de 1 como en versiones anteriores.
§
Decimal: Tipo
de datos para valores decimales. Se ha eliminado el tipo Currency y ahora todos los números con decimales son
de este tipo de dato.
§
Char: Tipo de dato para
almacenar un solo carácter. Al ser caracteres en unicode se almacena en 2
bytes.
§
Date: Ocupa 8 bytes y se usa
para almacenar fechas.
§
String: OBJETO para almacenar
cadenas de caracteres. Ahora deja de ser un tipo de dato y se convierte en un
objeto propiamente dicho. Con varias propiedades y funciones.
Ejemplos de definiciones de
datos
Dim a
as Int32
Dim b
as String
Dim c
as String = “Hola”
Dim d
as Int16 = 27
Dim e
as System.DateTime ‘ Equivale a e as Date
Aún así podemos seguir usando
los datos de Visual Basic 6, Single, Double, ... aunque es recomendable no
usarlos a no ser por problemas de compatibilidad.
Se pueden usar las siguientes abreviaturas conocidas ya por los programadores de C.
Los tipos de datos de Visual Basic .NET se puede agrupar en 2 grupos. Los tipos por valor y los tipos por referencia. Cuando creamos un dato por referencia lo que estamos creando es un puntero de 32 bits al dato real. Y cuando se hace una asignación de ese dato lo que se hace es una copia de ese puntero, lo que permite que tengamos 2 variables apuntando al mismo dato, y que modificando cualquiera de ellos el dato real se modifique.
Los datos por valor cuando se asignan lo que hacen es una copia de si mismos en la otra variable lo que permite trabajar sin modificar el valor de la variable asignada.
Ejemplos:
Dim cad1 as String = “Hola”
Dim cad2 as String = cad1
Cad2 = “Prueba”
Console.Writeline(“Cad1 = {0}, Cad2 = {1}”, cad1, cad2)
Dim int1 as Int16 = 25
Dim int2 as Int16 = int1
Int2 = 50
Console.Writeline(“int1 = {0}, int2 = {1}”, CStr(int1), CStr(int2))
Conversiones de datos
Como es normal, muchas veces tenemos que convertir un tipo de dato en otro.
Como vimos en el ejemplo anterior para mostrar las variables numéricas en una cadena antes debemos convertirlas para ello usamos las funciones de conversión especificas para cada tipo de dato, las mismas que en Visual Basic 6. (CStr, CDbl, CInt, ...)
Pero además tenemos otras 2 funciones que nos permiten convertir un tipo de dato en cualquier otro indicando su denominación.
§
CType: Si
nosotros creamos una clase llamada Persona, y queremos convertir un objeto en
ese tipo de dato usaríamos esta función puesto que no tenemos una función
directa que convierta tipos de datos a nuestras clases. Su uso seria el
siguiente:
Dim obj as Object
Ctype (obj, Persona)
§ DirectCast: La sintaxis es la misma que con Ctype, pero tiene algunas diferencias lógicas. Directcast solo trabaja con datos por referencia, por tanto las variables numéricas dan un error al ser convertidas mediante DirectCast. Otra diferencia es que solo funciona si el objeto puede ser convertido al destino, cosa que Ctype no hace.
Cuando se pueda usar DirectCast es recomendable usarlo puesto que es mas rápido que Ctype.
Constantes y enumeraciones
La definición de constantes y enumeraciones es similar a VB6.
Const: Con esta palabra reservada se crea una constante.
Public Const Contraseña as String = “password”
Esta seria una asignación correcta.
Para empezar crearemos un nuevo proyecto tipo Aplicación de Consola a la que llamaremos AppCon1.
Lo que nos sale en pantalla tras crear el proyecto es la
ventana de código que nos muestra el código general por defecto para este tipo
de aplicaciones.
Module Module1 Sub
Main() End Sub End Module
Nosotros vamos a realizar una aplicación que nos pida
nuestro nombre por pantalla y tras introducirlo y pulsar INTRO nos saludara y
nos día el día y la hora actuales.
Module AppCon1 Sub
Main() ' Variable para almacenar el nombre Dim
Nombre As String ' Pedimos el nombre por pantalla Console.Write("Escriba su
nombre: ") Nombre = Console.ReadLine ' Ahora saludamos y mostramos el día y la hora Console.WriteLine("¡Hola!,
{0}. Son las {1}", Nombre, Now) End Sub End Module
Como sucede con Visual Basic 6, la ‘ sirve para introducir
comentarios.
La declaración de variables es similar a la usada en las
versiones anteriores.
Para ejecutar la aplicación tenemos que pulsar F5, o el
símbolo de PLAY.
Como podeis observar, después de ejecutar la aplicación no
se muestra nada, para arreglar esto lo que debemos hacer es para el programa al
final puesto que lo que sucede es que como muestra el texto con mucha velocidad
y luego termina el programa pues no nos da tiempo a verlo.
Para corregir esto añadiremos la siguiente linea antes de End Sub.
Console.ReadLine()
Con esto conseguimos que al finalizar nos pida la pulsación
de la tecla INTRO antes de terminar el programa y asi podemos visualizar
perfectamente la linea donde se nos muestra la fecha.
Nota del autor: Now es una función
que devuelve la hora, para los que nunca hayan programado en visual basic.